diff --git a/.librarian/state.yaml b/.librarian/state.yaml index d3fc2a6845f8..42564a569892 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -2,7 +2,7 @@ image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-li libraries: - id: google-ads-admanager version: 0.5.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd + last_generated_commit: e8365a7f88fabe8717cb8322b8ce784b03b6daea apis: - path: google/ads/admanager/v1 service_config: admanager_v1.yaml @@ -129,7 +129,7 @@ libraries: tag_format: '{id}-v{version}' - id: google-apps-chat version: 0.3.0 - last_generated_commit: a9ebc23947a515fab3de97ff326c86fc8f03fae1 + last_generated_commit: e8365a7f88fabe8717cb8322b8ce784b03b6daea apis: - path: google/chat/v1 service_config: chat_v1.yaml @@ -566,7 +566,7 @@ libraries: tag_format: '{id}-v{version}' - id: google-cloud-audit-log version: 0.4.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd + last_generated_commit: e8365a7f88fabe8717cb8322b8ce784b03b6daea apis: - path: google/cloud/audit service_config: cloudaudit.yaml @@ -1178,7 +1178,7 @@ libraries: tag_format: '{id}-v{version}' - id: google-cloud-common version: 1.6.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd + last_generated_commit: e8365a7f88fabe8717cb8322b8ce784b03b6daea apis: - path: google/cloud/common service_config: common.yaml @@ -1513,7 +1513,7 @@ libraries: tag_format: '{id}-v{version}' - id: google-cloud-dataplex version: 2.13.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd + last_generated_commit: e8365a7f88fabe8717cb8322b8ce784b03b6daea apis: - path: google/cloud/dataplex/v1 service_config: dataplex_v1.yaml @@ -1652,7 +1652,7 @@ libraries: tag_format: '{id}-v{version}' - id: google-cloud-dialogflow version: 2.42.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd + last_generated_commit: e8365a7f88fabe8717cb8322b8ce784b03b6daea apis: - path: google/cloud/dialogflow/v2beta1 service_config: dialogflow_v2beta1.yaml @@ -4184,7 +4184,7 @@ libraries: tag_format: '{id}-v{version}' - id: google-maps-places version: 0.4.0 - last_generated_commit: 55319b058f8a0e46bbeeff30e374e4b1f081f494 + last_generated_commit: e8365a7f88fabe8717cb8322b8ce784b03b6daea apis: - path: google/maps/places/v1 service_config: places_v1.yaml @@ -4592,7 +4592,7 @@ libraries: tag_format: '{id}-v{version}' - id: googleapis-common-protos version: 1.71.0 - last_generated_commit: 3322511885371d2b2253f209ccc3aa60d4100cfd + last_generated_commit: e8365a7f88fabe8717cb8322b8ce784b03b6daea apis: - path: google/api service_config: serviceconfig.yaml diff --git a/packages/google-ads-admanager/docs/admanager_v1/ad_review_center_ad_service.rst b/packages/google-ads-admanager/docs/admanager_v1/ad_review_center_ad_service.rst new file mode 100644 index 000000000000..ba04c9407e5e --- /dev/null +++ b/packages/google-ads-admanager/docs/admanager_v1/ad_review_center_ad_service.rst @@ -0,0 +1,10 @@ +AdReviewCenterAdService +----------------------------------------- + +.. automodule:: google.ads.admanager_v1.services.ad_review_center_ad_service + :members: + :inherited-members: + +.. automodule:: google.ads.admanager_v1.services.ad_review_center_ad_service.pagers + :members: + :inherited-members: diff --git a/packages/google-ads-admanager/docs/admanager_v1/application_service.rst b/packages/google-ads-admanager/docs/admanager_v1/application_service.rst new file mode 100644 index 000000000000..c077f7b2cf1c --- /dev/null +++ b/packages/google-ads-admanager/docs/admanager_v1/application_service.rst @@ -0,0 +1,10 @@ +ApplicationService +------------------------------------ + +.. automodule:: google.ads.admanager_v1.services.application_service + :members: + :inherited-members: + +.. automodule:: google.ads.admanager_v1.services.application_service.pagers + :members: + :inherited-members: diff --git a/packages/google-ads-admanager/docs/admanager_v1/audience_segment_service.rst b/packages/google-ads-admanager/docs/admanager_v1/audience_segment_service.rst new file mode 100644 index 000000000000..6d0db5ba8786 --- /dev/null +++ b/packages/google-ads-admanager/docs/admanager_v1/audience_segment_service.rst @@ -0,0 +1,10 @@ +AudienceSegmentService +---------------------------------------- + +.. automodule:: google.ads.admanager_v1.services.audience_segment_service + :members: + :inherited-members: + +.. automodule:: google.ads.admanager_v1.services.audience_segment_service.pagers + :members: + :inherited-members: diff --git a/packages/google-ads-admanager/docs/admanager_v1/browser_language_service.rst b/packages/google-ads-admanager/docs/admanager_v1/browser_language_service.rst new file mode 100644 index 000000000000..5a736534bc13 --- /dev/null +++ b/packages/google-ads-admanager/docs/admanager_v1/browser_language_service.rst @@ -0,0 +1,10 @@ +BrowserLanguageService +---------------------------------------- + +.. automodule:: google.ads.admanager_v1.services.browser_language_service + :members: + :inherited-members: + +.. automodule:: google.ads.admanager_v1.services.browser_language_service.pagers + :members: + :inherited-members: diff --git a/packages/google-ads-admanager/docs/admanager_v1/browser_service.rst b/packages/google-ads-admanager/docs/admanager_v1/browser_service.rst new file mode 100644 index 000000000000..0f139f9406f5 --- /dev/null +++ b/packages/google-ads-admanager/docs/admanager_v1/browser_service.rst @@ -0,0 +1,10 @@ +BrowserService +-------------------------------- + +.. automodule:: google.ads.admanager_v1.services.browser_service + :members: + :inherited-members: + +.. automodule:: google.ads.admanager_v1.services.browser_service.pagers + :members: + :inherited-members: diff --git a/packages/google-ads-admanager/docs/admanager_v1/cms_metadata_key_service.rst b/packages/google-ads-admanager/docs/admanager_v1/cms_metadata_key_service.rst new file mode 100644 index 000000000000..585368244ffe --- /dev/null +++ b/packages/google-ads-admanager/docs/admanager_v1/cms_metadata_key_service.rst @@ -0,0 +1,10 @@ +CmsMetadataKeyService +--------------------------------------- + +.. automodule:: google.ads.admanager_v1.services.cms_metadata_key_service + :members: + :inherited-members: + +.. automodule:: google.ads.admanager_v1.services.cms_metadata_key_service.pagers + :members: + :inherited-members: diff --git a/packages/google-ads-admanager/docs/admanager_v1/cms_metadata_value_service.rst b/packages/google-ads-admanager/docs/admanager_v1/cms_metadata_value_service.rst new file mode 100644 index 000000000000..b7bb479e9530 --- /dev/null +++ b/packages/google-ads-admanager/docs/admanager_v1/cms_metadata_value_service.rst @@ -0,0 +1,10 @@ +CmsMetadataValueService +----------------------------------------- + +.. automodule:: google.ads.admanager_v1.services.cms_metadata_value_service + :members: + :inherited-members: + +.. automodule:: google.ads.admanager_v1.services.cms_metadata_value_service.pagers + :members: + :inherited-members: diff --git a/packages/google-ads-admanager/docs/admanager_v1/contact_service.rst b/packages/google-ads-admanager/docs/admanager_v1/contact_service.rst new file mode 100644 index 000000000000..478ccc08a803 --- /dev/null +++ b/packages/google-ads-admanager/docs/admanager_v1/contact_service.rst @@ -0,0 +1,10 @@ +ContactService +-------------------------------- + +.. automodule:: google.ads.admanager_v1.services.contact_service + :members: + :inherited-members: + +.. automodule:: google.ads.admanager_v1.services.contact_service.pagers + :members: + :inherited-members: diff --git a/packages/google-ads-admanager/docs/admanager_v1/content_bundle_service.rst b/packages/google-ads-admanager/docs/admanager_v1/content_bundle_service.rst new file mode 100644 index 000000000000..65dc981a3321 --- /dev/null +++ b/packages/google-ads-admanager/docs/admanager_v1/content_bundle_service.rst @@ -0,0 +1,10 @@ +ContentBundleService +-------------------------------------- + +.. automodule:: google.ads.admanager_v1.services.content_bundle_service + :members: + :inherited-members: + +.. automodule:: google.ads.admanager_v1.services.content_bundle_service.pagers + :members: + :inherited-members: diff --git a/packages/google-ads-admanager/docs/admanager_v1/content_label_service.rst b/packages/google-ads-admanager/docs/admanager_v1/content_label_service.rst new file mode 100644 index 000000000000..6e82b42d87e1 --- /dev/null +++ b/packages/google-ads-admanager/docs/admanager_v1/content_label_service.rst @@ -0,0 +1,10 @@ +ContentLabelService +------------------------------------- + +.. automodule:: google.ads.admanager_v1.services.content_label_service + :members: + :inherited-members: + +.. automodule:: google.ads.admanager_v1.services.content_label_service.pagers + :members: + :inherited-members: diff --git a/packages/google-ads-admanager/docs/admanager_v1/content_service.rst b/packages/google-ads-admanager/docs/admanager_v1/content_service.rst new file mode 100644 index 000000000000..835d0684f251 --- /dev/null +++ b/packages/google-ads-admanager/docs/admanager_v1/content_service.rst @@ -0,0 +1,10 @@ +ContentService +-------------------------------- + +.. automodule:: google.ads.admanager_v1.services.content_service + :members: + :inherited-members: + +.. automodule:: google.ads.admanager_v1.services.content_service.pagers + :members: + :inherited-members: diff --git a/packages/google-ads-admanager/docs/admanager_v1/creative_template_service.rst b/packages/google-ads-admanager/docs/admanager_v1/creative_template_service.rst new file mode 100644 index 000000000000..69b67eff7d30 --- /dev/null +++ b/packages/google-ads-admanager/docs/admanager_v1/creative_template_service.rst @@ -0,0 +1,10 @@ +CreativeTemplateService +----------------------------------------- + +.. automodule:: google.ads.admanager_v1.services.creative_template_service + :members: + :inherited-members: + +.. automodule:: google.ads.admanager_v1.services.creative_template_service.pagers + :members: + :inherited-members: diff --git a/packages/google-ads-admanager/docs/admanager_v1/device_capability_service.rst b/packages/google-ads-admanager/docs/admanager_v1/device_capability_service.rst new file mode 100644 index 000000000000..858d1753889a --- /dev/null +++ b/packages/google-ads-admanager/docs/admanager_v1/device_capability_service.rst @@ -0,0 +1,10 @@ +DeviceCapabilityService +----------------------------------------- + +.. automodule:: google.ads.admanager_v1.services.device_capability_service + :members: + :inherited-members: + +.. automodule:: google.ads.admanager_v1.services.device_capability_service.pagers + :members: + :inherited-members: diff --git a/packages/google-ads-admanager/docs/admanager_v1/device_manufacturer_service.rst b/packages/google-ads-admanager/docs/admanager_v1/device_manufacturer_service.rst new file mode 100644 index 000000000000..a87276a258c4 --- /dev/null +++ b/packages/google-ads-admanager/docs/admanager_v1/device_manufacturer_service.rst @@ -0,0 +1,10 @@ +DeviceManufacturerService +------------------------------------------- + +.. automodule:: google.ads.admanager_v1.services.device_manufacturer_service + :members: + :inherited-members: + +.. automodule:: google.ads.admanager_v1.services.device_manufacturer_service.pagers + :members: + :inherited-members: diff --git a/packages/google-ads-admanager/docs/admanager_v1/mobile_carrier_service.rst b/packages/google-ads-admanager/docs/admanager_v1/mobile_carrier_service.rst new file mode 100644 index 000000000000..4401df337532 --- /dev/null +++ b/packages/google-ads-admanager/docs/admanager_v1/mobile_carrier_service.rst @@ -0,0 +1,10 @@ +MobileCarrierService +-------------------------------------- + +.. automodule:: google.ads.admanager_v1.services.mobile_carrier_service + :members: + :inherited-members: + +.. automodule:: google.ads.admanager_v1.services.mobile_carrier_service.pagers + :members: + :inherited-members: diff --git a/packages/google-ads-admanager/docs/admanager_v1/mobile_device_service.rst b/packages/google-ads-admanager/docs/admanager_v1/mobile_device_service.rst new file mode 100644 index 000000000000..8a7216fe71d1 --- /dev/null +++ b/packages/google-ads-admanager/docs/admanager_v1/mobile_device_service.rst @@ -0,0 +1,10 @@ +MobileDeviceService +------------------------------------- + +.. automodule:: google.ads.admanager_v1.services.mobile_device_service + :members: + :inherited-members: + +.. automodule:: google.ads.admanager_v1.services.mobile_device_service.pagers + :members: + :inherited-members: diff --git a/packages/google-ads-admanager/docs/admanager_v1/mobile_device_submodel_service.rst b/packages/google-ads-admanager/docs/admanager_v1/mobile_device_submodel_service.rst new file mode 100644 index 000000000000..c84445eb0716 --- /dev/null +++ b/packages/google-ads-admanager/docs/admanager_v1/mobile_device_submodel_service.rst @@ -0,0 +1,10 @@ +MobileDeviceSubmodelService +--------------------------------------------- + +.. automodule:: google.ads.admanager_v1.services.mobile_device_submodel_service + :members: + :inherited-members: + +.. automodule:: google.ads.admanager_v1.services.mobile_device_submodel_service.pagers + :members: + :inherited-members: diff --git a/packages/google-ads-admanager/docs/admanager_v1/services_.rst b/packages/google-ads-admanager/docs/admanager_v1/services_.rst index 8d1f20905268..3b4081b8c595 100644 --- a/packages/google-ads-admanager/docs/admanager_v1/services_.rst +++ b/packages/google-ads-admanager/docs/admanager_v1/services_.rst @@ -4,15 +4,32 @@ Services for Google Ads Admanager v1 API :maxdepth: 2 ad_break_service + ad_review_center_ad_service ad_unit_service + application_service + audience_segment_service bandwidth_group_service + browser_language_service + browser_service + cms_metadata_key_service + cms_metadata_value_service company_service + contact_service + content_bundle_service + content_label_service + content_service + creative_template_service custom_field_service custom_targeting_key_service custom_targeting_value_service + device_capability_service device_category_service + device_manufacturer_service entity_signals_mapping_service geo_target_service + mobile_carrier_service + mobile_device_service + mobile_device_submodel_service network_service operating_system_service operating_system_version_service @@ -23,5 +40,7 @@ Services for Google Ads Admanager v1 API programmatic_buyer_service report_service role_service + site_service taxonomy_category_service + team_service user_service diff --git a/packages/google-ads-admanager/docs/admanager_v1/site_service.rst b/packages/google-ads-admanager/docs/admanager_v1/site_service.rst new file mode 100644 index 000000000000..cd5c63fb219b --- /dev/null +++ b/packages/google-ads-admanager/docs/admanager_v1/site_service.rst @@ -0,0 +1,10 @@ +SiteService +----------------------------- + +.. automodule:: google.ads.admanager_v1.services.site_service + :members: + :inherited-members: + +.. automodule:: google.ads.admanager_v1.services.site_service.pagers + :members: + :inherited-members: diff --git a/packages/google-ads-admanager/docs/admanager_v1/team_service.rst b/packages/google-ads-admanager/docs/admanager_v1/team_service.rst new file mode 100644 index 000000000000..4d3e14c6f6c1 --- /dev/null +++ b/packages/google-ads-admanager/docs/admanager_v1/team_service.rst @@ -0,0 +1,10 @@ +TeamService +----------------------------- + +.. automodule:: google.ads.admanager_v1.services.team_service + :members: + :inherited-members: + +.. automodule:: google.ads.admanager_v1.services.team_service.pagers + :members: + :inherited-members: diff --git a/packages/google-ads-admanager/google/ads/admanager/__init__.py b/packages/google-ads-admanager/google/ads/admanager/__init__.py index daa401ad019c..fb4253051c0b 100644 --- a/packages/google-ads-admanager/google/ads/admanager/__init__.py +++ b/packages/google-ads-admanager/google/ads/admanager/__init__.py @@ -21,11 +21,41 @@ from google.ads.admanager_v1.services.ad_break_service.client import ( AdBreakServiceClient, ) +from google.ads.admanager_v1.services.ad_review_center_ad_service.client import ( + AdReviewCenterAdServiceClient, +) from google.ads.admanager_v1.services.ad_unit_service.client import AdUnitServiceClient +from google.ads.admanager_v1.services.application_service.client import ( + ApplicationServiceClient, +) +from google.ads.admanager_v1.services.audience_segment_service.client import ( + AudienceSegmentServiceClient, +) from google.ads.admanager_v1.services.bandwidth_group_service.client import ( BandwidthGroupServiceClient, ) +from google.ads.admanager_v1.services.browser_language_service.client import ( + BrowserLanguageServiceClient, +) +from google.ads.admanager_v1.services.browser_service.client import BrowserServiceClient +from google.ads.admanager_v1.services.cms_metadata_key_service.client import ( + CmsMetadataKeyServiceClient, +) +from google.ads.admanager_v1.services.cms_metadata_value_service.client import ( + CmsMetadataValueServiceClient, +) from google.ads.admanager_v1.services.company_service.client import CompanyServiceClient +from google.ads.admanager_v1.services.contact_service.client import ContactServiceClient +from google.ads.admanager_v1.services.content_bundle_service.client import ( + ContentBundleServiceClient, +) +from google.ads.admanager_v1.services.content_label_service.client import ( + ContentLabelServiceClient, +) +from google.ads.admanager_v1.services.content_service.client import ContentServiceClient +from google.ads.admanager_v1.services.creative_template_service.client import ( + CreativeTemplateServiceClient, +) from google.ads.admanager_v1.services.custom_field_service.client import ( CustomFieldServiceClient, ) @@ -35,15 +65,30 @@ from google.ads.admanager_v1.services.custom_targeting_value_service.client import ( CustomTargetingValueServiceClient, ) +from google.ads.admanager_v1.services.device_capability_service.client import ( + DeviceCapabilityServiceClient, +) from google.ads.admanager_v1.services.device_category_service.client import ( DeviceCategoryServiceClient, ) +from google.ads.admanager_v1.services.device_manufacturer_service.client import ( + DeviceManufacturerServiceClient, +) from google.ads.admanager_v1.services.entity_signals_mapping_service.client import ( EntitySignalsMappingServiceClient, ) from google.ads.admanager_v1.services.geo_target_service.client import ( GeoTargetServiceClient, ) +from google.ads.admanager_v1.services.mobile_carrier_service.client import ( + MobileCarrierServiceClient, +) +from google.ads.admanager_v1.services.mobile_device_service.client import ( + MobileDeviceServiceClient, +) +from google.ads.admanager_v1.services.mobile_device_submodel_service.client import ( + MobileDeviceSubmodelServiceClient, +) from google.ads.admanager_v1.services.network_service.client import NetworkServiceClient from google.ads.admanager_v1.services.operating_system_service.client import ( OperatingSystemServiceClient, @@ -66,9 +111,11 @@ ) from google.ads.admanager_v1.services.report_service.client import ReportServiceClient from google.ads.admanager_v1.services.role_service.client import RoleServiceClient +from google.ads.admanager_v1.services.site_service.client import SiteServiceClient from google.ads.admanager_v1.services.taxonomy_category_service.client import ( TaxonomyCategoryServiceClient, ) +from google.ads.admanager_v1.services.team_service.client import TeamServiceClient from google.ads.admanager_v1.services.user_service.client import UserServiceClient from google.ads.admanager_v1.types.ad_break_messages import AdBreak from google.ads.admanager_v1.types.ad_break_service import ( @@ -79,6 +126,19 @@ ListAdBreaksResponse, UpdateAdBreakRequest, ) +from google.ads.admanager_v1.types.ad_review_center_ad_enums import ( + AdReviewCenterAdStatusEnum, +) +from google.ads.admanager_v1.types.ad_review_center_ad_messages import AdReviewCenterAd +from google.ads.admanager_v1.types.ad_review_center_ad_service import ( + BatchAdReviewCenterAdsOperationMetadata, + BatchAllowAdReviewCenterAdsRequest, + BatchAllowAdReviewCenterAdsResponse, + BatchBlockAdReviewCenterAdsRequest, + BatchBlockAdReviewCenterAdsResponse, + SearchAdReviewCenterAdsRequest, + SearchAdReviewCenterAdsResponse, +) from google.ads.admanager_v1.types.ad_unit_enums import ( AdUnitStatusEnum, SmartSizeModeEnum, @@ -98,13 +158,55 @@ ListAdUnitsResponse, ) from google.ads.admanager_v1.types.admanager_error import AdManagerError +from google.ads.admanager_v1.types.application_messages import Application +from google.ads.admanager_v1.types.application_service import ( + GetApplicationRequest, + ListApplicationsRequest, + ListApplicationsResponse, +) from google.ads.admanager_v1.types.applied_label import AppliedLabel +from google.ads.admanager_v1.types.audience_segment_messages import AudienceSegment +from google.ads.admanager_v1.types.audience_segment_service import ( + GetAudienceSegmentRequest, + ListAudienceSegmentsRequest, + ListAudienceSegmentsResponse, +) from google.ads.admanager_v1.types.bandwidth_group_messages import BandwidthGroup from google.ads.admanager_v1.types.bandwidth_group_service import ( GetBandwidthGroupRequest, ListBandwidthGroupsRequest, ListBandwidthGroupsResponse, ) +from google.ads.admanager_v1.types.browser_language_messages import BrowserLanguage +from google.ads.admanager_v1.types.browser_language_service import ( + GetBrowserLanguageRequest, + ListBrowserLanguagesRequest, + ListBrowserLanguagesResponse, +) +from google.ads.admanager_v1.types.browser_messages import Browser +from google.ads.admanager_v1.types.browser_service import ( + GetBrowserRequest, + ListBrowsersRequest, + ListBrowsersResponse, +) +from google.ads.admanager_v1.types.cms_metadata_key_enums import ( + CmsMetadataKeyStatusEnum, +) +from google.ads.admanager_v1.types.cms_metadata_key_messages import CmsMetadataKey +from google.ads.admanager_v1.types.cms_metadata_key_service import ( + GetCmsMetadataKeyRequest, + ListCmsMetadataKeysRequest, + ListCmsMetadataKeysResponse, +) +from google.ads.admanager_v1.types.cms_metadata_value_enums import ( + CmsMetadataValueStatusEnum, +) +from google.ads.admanager_v1.types.cms_metadata_value_messages import CmsMetadataValue +from google.ads.admanager_v1.types.cms_metadata_value_service import ( + GetCmsMetadataValueRequest, + ListCmsMetadataValuesRequest, + ListCmsMetadataValuesResponse, +) from google.ads.admanager_v1.types.company_enums import ( CompanyCreditStatusEnum, CompanyTypeEnum, @@ -115,7 +217,53 @@ ListCompaniesRequest, ListCompaniesResponse, ) +from google.ads.admanager_v1.types.contact_enums import ContactStatusEnum from google.ads.admanager_v1.types.contact_messages import Contact +from google.ads.admanager_v1.types.contact_service import ( + BatchCreateContactsRequest, + BatchCreateContactsResponse, + BatchUpdateContactsRequest, + BatchUpdateContactsResponse, + CreateContactRequest, + GetContactRequest, + ListContactsRequest, + ListContactsResponse, + UpdateContactRequest, +) +from google.ads.admanager_v1.types.content_bundle_messages import ContentBundle +from google.ads.admanager_v1.types.content_bundle_service import ( + GetContentBundleRequest, + ListContentBundlesRequest, + ListContentBundlesResponse, +) +from google.ads.admanager_v1.types.content_label_messages import ContentLabel +from google.ads.admanager_v1.types.content_label_service import ( + GetContentLabelRequest, + ListContentLabelsRequest, + ListContentLabelsResponse, +) +from google.ads.admanager_v1.types.content_messages import Content +from google.ads.admanager_v1.types.content_service import ( + GetContentRequest, + ListContentRequest, + ListContentResponse, +) +from google.ads.admanager_v1.types.creative_template_enums import ( + CreativeTemplateStatusEnum, + CreativeTemplateTypeEnum, +) +from google.ads.admanager_v1.types.creative_template_messages import ( + CreativeTemplate, + CreativeTemplateVariable, +) +from google.ads.admanager_v1.types.creative_template_service import ( + GetCreativeTemplateRequest, + ListCreativeTemplatesRequest, + ListCreativeTemplatesResponse, +) +from google.ads.admanager_v1.types.creative_template_variable_url_type_enum import ( + CreativeTemplateVariableUrlTypeEnum, +) from google.ads.admanager_v1.types.custom_field_enums import ( CustomFieldDataTypeEnum, CustomFieldEntityTypeEnum, @@ -127,9 +275,19 @@ CustomFieldOption, ) from google.ads.admanager_v1.types.custom_field_service import ( + BatchActivateCustomFieldsRequest, + BatchActivateCustomFieldsResponse, + BatchCreateCustomFieldsRequest, + BatchCreateCustomFieldsResponse, + BatchDeactivateCustomFieldsRequest, + BatchDeactivateCustomFieldsResponse, + BatchUpdateCustomFieldsRequest, + BatchUpdateCustomFieldsResponse, + CreateCustomFieldRequest, GetCustomFieldRequest, ListCustomFieldsRequest, ListCustomFieldsResponse, + UpdateCustomFieldRequest, ) from google.ads.admanager_v1.types.custom_field_value import CustomFieldValue from google.ads.admanager_v1.types.custom_targeting_key_enums import ( @@ -160,12 +318,26 @@ from google.ads.admanager_v1.types.deal_buyer_permission_type_enum import ( DealBuyerPermissionTypeEnum, ) +from google.ads.admanager_v1.types.device_capability_messages import DeviceCapability +from google.ads.admanager_v1.types.device_capability_service import ( + GetDeviceCapabilityRequest, + ListDeviceCapabilitiesRequest, + ListDeviceCapabilitiesResponse, +) from google.ads.admanager_v1.types.device_category_messages import DeviceCategory from google.ads.admanager_v1.types.device_category_service import ( GetDeviceCategoryRequest, ListDeviceCategoriesRequest, ListDeviceCategoriesResponse, ) +from google.ads.admanager_v1.types.device_manufacturer_messages import ( + DeviceManufacturer, +) +from google.ads.admanager_v1.types.device_manufacturer_service import ( + GetDeviceManufacturerRequest, + ListDeviceManufacturersRequest, + ListDeviceManufacturersResponse, +) from google.ads.admanager_v1.types.early_ad_break_notification_enums import ( AdBreakStateEnum, ) @@ -184,6 +356,9 @@ UpdateEntitySignalsMappingRequest, ) from google.ads.admanager_v1.types.environment_type_enum import EnvironmentTypeEnum +from google.ads.admanager_v1.types.exchange_syndication_product_enum import ( + ExchangeSyndicationProductEnum, +) from google.ads.admanager_v1.types.frequency_cap import FrequencyCap from google.ads.admanager_v1.types.geo_target_messages import GeoTarget from google.ads.admanager_v1.types.geo_target_service import ( @@ -193,6 +368,26 @@ ) from google.ads.admanager_v1.types.label_messages import Label from google.ads.admanager_v1.types.live_stream_event_messages import LiveStreamEvent +from google.ads.admanager_v1.types.mobile_carrier_messages import MobileCarrier +from google.ads.admanager_v1.types.mobile_carrier_service import ( + GetMobileCarrierRequest, + ListMobileCarriersRequest, + ListMobileCarriersResponse, +) +from google.ads.admanager_v1.types.mobile_device_messages import MobileDevice +from google.ads.admanager_v1.types.mobile_device_service import ( + GetMobileDeviceRequest, + ListMobileDevicesRequest, + ListMobileDevicesResponse, +) +from google.ads.admanager_v1.types.mobile_device_submodel_messages import ( + MobileDeviceSubmodel, +) +from google.ads.admanager_v1.types.mobile_device_submodel_service import ( + GetMobileDeviceSubmodelRequest, + ListMobileDeviceSubmodelsRequest, + ListMobileDeviceSubmodelsResponse, +) from google.ads.admanager_v1.types.network_messages import Network from google.ads.admanager_v1.types.network_service import ( GetNetworkRequest, @@ -223,9 +418,21 @@ from google.ads.admanager_v1.types.placement_enums import PlacementStatusEnum from google.ads.admanager_v1.types.placement_messages import Placement from google.ads.admanager_v1.types.placement_service import ( + BatchActivatePlacementsRequest, + BatchActivatePlacementsResponse, + BatchArchivePlacementsRequest, + BatchArchivePlacementsResponse, + BatchCreatePlacementsRequest, + BatchCreatePlacementsResponse, + BatchDeactivatePlacementsRequest, + BatchDeactivatePlacementsResponse, + BatchUpdatePlacementsRequest, + BatchUpdatePlacementsResponse, + CreatePlacementRequest, GetPlacementRequest, ListPlacementsRequest, ListPlacementsResponse, + UpdatePlacementRequest, ) from google.ads.admanager_v1.types.private_auction_deal_messages import ( PrivateAuctionDeal, @@ -254,10 +461,10 @@ ListProgrammaticBuyersRequest, ListProgrammaticBuyersResponse, ) +from google.ads.admanager_v1.types.report_definition import ReportDefinition from google.ads.admanager_v1.types.report_messages import ( Report, - ReportDefinition, - Schedule, + ReportDataTable, ScheduleOptions, ) from google.ads.admanager_v1.types.report_service import ( @@ -272,6 +479,7 @@ RunReportResponse, UpdateReportRequest, ) +from google.ads.admanager_v1.types.report_value import ReportValue from google.ads.admanager_v1.types.request_platform_enum import RequestPlatformEnum from google.ads.admanager_v1.types.role_enums import RoleStatusEnum from google.ads.admanager_v1.types.role_messages import Role @@ -280,6 +488,26 @@ ListRolesRequest, ListRolesResponse, ) +from google.ads.admanager_v1.types.site_enums import ( + SiteApprovalStatusEnum, + SiteDisapprovalReasonEnum, +) +from google.ads.admanager_v1.types.site_messages import DisapprovalReason, Site +from google.ads.admanager_v1.types.site_service import ( + BatchCreateSitesRequest, + BatchCreateSitesResponse, + BatchDeactivateSitesRequest, + BatchDeactivateSitesResponse, + BatchSubmitSitesForApprovalRequest, + BatchSubmitSitesForApprovalResponse, + BatchUpdateSitesRequest, + BatchUpdateSitesResponse, + CreateSiteRequest, + GetSiteRequest, + ListSitesRequest, + ListSitesResponse, + UpdateSiteRequest, +) from google.ads.admanager_v1.types.size import Size from google.ads.admanager_v1.types.size_type_enum import SizeTypeEnum from google.ads.admanager_v1.types.targeted_video_bumper_type_enum import ( @@ -287,14 +515,24 @@ ) from google.ads.admanager_v1.types.targeting import ( AdUnitTargeting, + AudienceSegmentTargeting, BandwidthTargeting, + BrowserLanguageTargeting, + BrowserTargeting, + CmsMetadataTargeting, + ContentTargeting, CustomTargeting, CustomTargetingClause, CustomTargetingLiteral, DataSegmentTargeting, + DeviceCapabilityTargeting, DeviceCategoryTargeting, + DeviceManufacturerTargeting, + FirstPartyMobileApplicationTargeting, GeoTargeting, InventoryTargeting, + MobileApplicationTargeting, + MobileCarrierTargeting, OperatingSystemTargeting, RequestPlatformTargeting, Targeting, @@ -310,23 +548,57 @@ ListTaxonomyCategoriesResponse, ) from google.ads.admanager_v1.types.taxonomy_type_enum import TaxonomyTypeEnum +from google.ads.admanager_v1.types.team_enums import TeamAccessTypeEnum, TeamStatusEnum from google.ads.admanager_v1.types.team_messages import Team +from google.ads.admanager_v1.types.team_service import ( + BatchActivateTeamsRequest, + BatchActivateTeamsResponse, + BatchCreateTeamsRequest, + BatchCreateTeamsResponse, + BatchDeactivateTeamsRequest, + BatchDeactivateTeamsResponse, + BatchUpdateTeamsRequest, + BatchUpdateTeamsResponse, + CreateTeamRequest, + GetTeamRequest, + ListTeamsRequest, + ListTeamsResponse, + UpdateTeamRequest, +) from google.ads.admanager_v1.types.time_unit_enum import TimeUnitEnum from google.ads.admanager_v1.types.user_messages import User from google.ads.admanager_v1.types.user_service import GetUserRequest from google.ads.admanager_v1.types.video_position_enum import VideoPositionEnum +from google.ads.admanager_v1.types.web_property import WebProperty __all__ = ( "AdBreakServiceClient", + "AdReviewCenterAdServiceClient", "AdUnitServiceClient", + "ApplicationServiceClient", + "AudienceSegmentServiceClient", "BandwidthGroupServiceClient", + "BrowserLanguageServiceClient", + "BrowserServiceClient", + "CmsMetadataKeyServiceClient", + "CmsMetadataValueServiceClient", "CompanyServiceClient", + "ContactServiceClient", + "ContentBundleServiceClient", + "ContentLabelServiceClient", + "ContentServiceClient", + "CreativeTemplateServiceClient", "CustomFieldServiceClient", "CustomTargetingKeyServiceClient", "CustomTargetingValueServiceClient", + "DeviceCapabilityServiceClient", "DeviceCategoryServiceClient", + "DeviceManufacturerServiceClient", "EntitySignalsMappingServiceClient", "GeoTargetServiceClient", + "MobileCarrierServiceClient", + "MobileDeviceServiceClient", + "MobileDeviceSubmodelServiceClient", "NetworkServiceClient", "OperatingSystemServiceClient", "OperatingSystemVersionServiceClient", @@ -337,7 +609,9 @@ "ProgrammaticBuyerServiceClient", "ReportServiceClient", "RoleServiceClient", + "SiteServiceClient", "TaxonomyCategoryServiceClient", + "TeamServiceClient", "UserServiceClient", "AdBreak", "CreateAdBreakRequest", @@ -346,6 +620,15 @@ "ListAdBreaksRequest", "ListAdBreaksResponse", "UpdateAdBreakRequest", + "AdReviewCenterAdStatusEnum", + "AdReviewCenterAd", + "BatchAdReviewCenterAdsOperationMetadata", + "BatchAllowAdReviewCenterAdsRequest", + "BatchAllowAdReviewCenterAdsResponse", + "BatchBlockAdReviewCenterAdsRequest", + "BatchBlockAdReviewCenterAdsResponse", + "SearchAdReviewCenterAdsRequest", + "SearchAdReviewCenterAdsResponse", "AdUnitStatusEnum", "SmartSizeModeEnum", "TargetWindowEnum", @@ -359,27 +642,93 @@ "ListAdUnitsRequest", "ListAdUnitsResponse", "AdManagerError", + "Application", + "GetApplicationRequest", + "ListApplicationsRequest", + "ListApplicationsResponse", "AppliedLabel", + "AudienceSegment", + "GetAudienceSegmentRequest", + "ListAudienceSegmentsRequest", + "ListAudienceSegmentsResponse", "BandwidthGroup", "GetBandwidthGroupRequest", "ListBandwidthGroupsRequest", "ListBandwidthGroupsResponse", + "BrowserLanguage", + "GetBrowserLanguageRequest", + "ListBrowserLanguagesRequest", + "ListBrowserLanguagesResponse", + "Browser", + "GetBrowserRequest", + "ListBrowsersRequest", + "ListBrowsersResponse", + "CmsMetadataKeyStatusEnum", + "CmsMetadataKey", + "GetCmsMetadataKeyRequest", + "ListCmsMetadataKeysRequest", + "ListCmsMetadataKeysResponse", + "CmsMetadataValueStatusEnum", + "CmsMetadataValue", + "GetCmsMetadataValueRequest", + "ListCmsMetadataValuesRequest", + "ListCmsMetadataValuesResponse", "CompanyCreditStatusEnum", "CompanyTypeEnum", "Company", "GetCompanyRequest", "ListCompaniesRequest", "ListCompaniesResponse", + "ContactStatusEnum", "Contact", + "BatchCreateContactsRequest", + "BatchCreateContactsResponse", + "BatchUpdateContactsRequest", + "BatchUpdateContactsResponse", + "CreateContactRequest", + "GetContactRequest", + "ListContactsRequest", + "ListContactsResponse", + "UpdateContactRequest", + "ContentBundle", + "GetContentBundleRequest", + "ListContentBundlesRequest", + "ListContentBundlesResponse", + "ContentLabel", + "GetContentLabelRequest", + "ListContentLabelsRequest", + "ListContentLabelsResponse", + "Content", + "GetContentRequest", + "ListContentRequest", + "ListContentResponse", + "CreativeTemplateStatusEnum", + "CreativeTemplateTypeEnum", + "CreativeTemplate", + "CreativeTemplateVariable", + "GetCreativeTemplateRequest", + "ListCreativeTemplatesRequest", + "ListCreativeTemplatesResponse", + "CreativeTemplateVariableUrlTypeEnum", "CustomFieldDataTypeEnum", "CustomFieldEntityTypeEnum", "CustomFieldStatusEnum", "CustomFieldVisibilityEnum", "CustomField", "CustomFieldOption", + "BatchActivateCustomFieldsRequest", + "BatchActivateCustomFieldsResponse", + "BatchCreateCustomFieldsRequest", + "BatchCreateCustomFieldsResponse", + "BatchDeactivateCustomFieldsRequest", + "BatchDeactivateCustomFieldsResponse", + "BatchUpdateCustomFieldsRequest", + "BatchUpdateCustomFieldsResponse", + "CreateCustomFieldRequest", "GetCustomFieldRequest", "ListCustomFieldsRequest", "ListCustomFieldsResponse", + "UpdateCustomFieldRequest", "CustomFieldValue", "CustomTargetingKeyReportableTypeEnum", "CustomTargetingKeyStatusEnum", @@ -395,10 +744,18 @@ "ListCustomTargetingValuesRequest", "ListCustomTargetingValuesResponse", "DealBuyerPermissionTypeEnum", + "DeviceCapability", + "GetDeviceCapabilityRequest", + "ListDeviceCapabilitiesRequest", + "ListDeviceCapabilitiesResponse", "DeviceCategory", "GetDeviceCategoryRequest", "ListDeviceCategoriesRequest", "ListDeviceCategoriesResponse", + "DeviceManufacturer", + "GetDeviceManufacturerRequest", + "ListDeviceManufacturersRequest", + "ListDeviceManufacturersResponse", "AdBreakStateEnum", "EntitySignalsMapping", "BatchCreateEntitySignalsMappingsRequest", @@ -411,6 +768,7 @@ "ListEntitySignalsMappingsResponse", "UpdateEntitySignalsMappingRequest", "EnvironmentTypeEnum", + "ExchangeSyndicationProductEnum", "FrequencyCap", "GeoTarget", "GetGeoTargetRequest", @@ -418,6 +776,18 @@ "ListGeoTargetsResponse", "Label", "LiveStreamEvent", + "MobileCarrier", + "GetMobileCarrierRequest", + "ListMobileCarriersRequest", + "ListMobileCarriersResponse", + "MobileDevice", + "GetMobileDeviceRequest", + "ListMobileDevicesRequest", + "ListMobileDevicesResponse", + "MobileDeviceSubmodel", + "GetMobileDeviceSubmodelRequest", + "ListMobileDeviceSubmodelsRequest", + "ListMobileDeviceSubmodelsResponse", "Network", "GetNetworkRequest", "ListNetworksRequest", @@ -437,9 +807,21 @@ "ListOrdersResponse", "PlacementStatusEnum", "Placement", + "BatchActivatePlacementsRequest", + "BatchActivatePlacementsResponse", + "BatchArchivePlacementsRequest", + "BatchArchivePlacementsResponse", + "BatchCreatePlacementsRequest", + "BatchCreatePlacementsResponse", + "BatchDeactivatePlacementsRequest", + "BatchDeactivatePlacementsResponse", + "BatchUpdatePlacementsRequest", + "BatchUpdatePlacementsResponse", + "CreatePlacementRequest", "GetPlacementRequest", "ListPlacementsRequest", "ListPlacementsResponse", + "UpdatePlacementRequest", "PrivateAuctionDeal", "CreatePrivateAuctionDealRequest", "GetPrivateAuctionDealRequest", @@ -457,9 +839,9 @@ "GetProgrammaticBuyerRequest", "ListProgrammaticBuyersRequest", "ListProgrammaticBuyersResponse", - "Report", "ReportDefinition", - "Schedule", + "Report", + "ReportDataTable", "ScheduleOptions", "CreateReportRequest", "FetchReportResultRowsRequest", @@ -471,24 +853,52 @@ "RunReportRequest", "RunReportResponse", "UpdateReportRequest", + "ReportValue", "RequestPlatformEnum", "RoleStatusEnum", "Role", "GetRoleRequest", "ListRolesRequest", "ListRolesResponse", + "SiteApprovalStatusEnum", + "SiteDisapprovalReasonEnum", + "DisapprovalReason", + "Site", + "BatchCreateSitesRequest", + "BatchCreateSitesResponse", + "BatchDeactivateSitesRequest", + "BatchDeactivateSitesResponse", + "BatchSubmitSitesForApprovalRequest", + "BatchSubmitSitesForApprovalResponse", + "BatchUpdateSitesRequest", + "BatchUpdateSitesResponse", + "CreateSiteRequest", + "GetSiteRequest", + "ListSitesRequest", + "ListSitesResponse", + "UpdateSiteRequest", "Size", "SizeTypeEnum", "TargetedVideoBumperTypeEnum", "AdUnitTargeting", + "AudienceSegmentTargeting", "BandwidthTargeting", + "BrowserLanguageTargeting", + "BrowserTargeting", + "CmsMetadataTargeting", + "ContentTargeting", "CustomTargeting", "CustomTargetingClause", "CustomTargetingLiteral", "DataSegmentTargeting", + "DeviceCapabilityTargeting", "DeviceCategoryTargeting", + "DeviceManufacturerTargeting", + "FirstPartyMobileApplicationTargeting", "GeoTargeting", "InventoryTargeting", + "MobileApplicationTargeting", + "MobileCarrierTargeting", "OperatingSystemTargeting", "RequestPlatformTargeting", "Targeting", @@ -501,9 +911,25 @@ "ListTaxonomyCategoriesRequest", "ListTaxonomyCategoriesResponse", "TaxonomyTypeEnum", + "TeamAccessTypeEnum", + "TeamStatusEnum", "Team", + "BatchActivateTeamsRequest", + "BatchActivateTeamsResponse", + "BatchCreateTeamsRequest", + "BatchCreateTeamsResponse", + "BatchDeactivateTeamsRequest", + "BatchDeactivateTeamsResponse", + "BatchUpdateTeamsRequest", + "BatchUpdateTeamsResponse", + "CreateTeamRequest", + "GetTeamRequest", + "ListTeamsRequest", + "ListTeamsResponse", + "UpdateTeamRequest", "TimeUnitEnum", "User", "GetUserRequest", "VideoPositionEnum", + "WebProperty", ) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/__init__.py index f4be94c5e588..9a216894a13e 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/__init__.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/__init__.py @@ -19,15 +19,32 @@ from .services.ad_break_service import AdBreakServiceClient +from .services.ad_review_center_ad_service import AdReviewCenterAdServiceClient from .services.ad_unit_service import AdUnitServiceClient +from .services.application_service import ApplicationServiceClient +from .services.audience_segment_service import AudienceSegmentServiceClient from .services.bandwidth_group_service import BandwidthGroupServiceClient +from .services.browser_language_service import BrowserLanguageServiceClient +from .services.browser_service import BrowserServiceClient +from .services.cms_metadata_key_service import CmsMetadataKeyServiceClient +from .services.cms_metadata_value_service import CmsMetadataValueServiceClient from .services.company_service import CompanyServiceClient +from .services.contact_service import ContactServiceClient +from .services.content_bundle_service import ContentBundleServiceClient +from .services.content_label_service import ContentLabelServiceClient +from .services.content_service import ContentServiceClient +from .services.creative_template_service import CreativeTemplateServiceClient from .services.custom_field_service import CustomFieldServiceClient from .services.custom_targeting_key_service import CustomTargetingKeyServiceClient from .services.custom_targeting_value_service import CustomTargetingValueServiceClient +from .services.device_capability_service import DeviceCapabilityServiceClient from .services.device_category_service import DeviceCategoryServiceClient +from .services.device_manufacturer_service import DeviceManufacturerServiceClient from .services.entity_signals_mapping_service import EntitySignalsMappingServiceClient from .services.geo_target_service import GeoTargetServiceClient +from .services.mobile_carrier_service import MobileCarrierServiceClient +from .services.mobile_device_service import MobileDeviceServiceClient +from .services.mobile_device_submodel_service import MobileDeviceSubmodelServiceClient from .services.network_service import NetworkServiceClient from .services.operating_system_service import OperatingSystemServiceClient from .services.operating_system_version_service import ( @@ -40,7 +57,9 @@ from .services.programmatic_buyer_service import ProgrammaticBuyerServiceClient from .services.report_service import ReportServiceClient from .services.role_service import RoleServiceClient +from .services.site_service import SiteServiceClient from .services.taxonomy_category_service import TaxonomyCategoryServiceClient +from .services.team_service import TeamServiceClient from .services.user_service import UserServiceClient from .types.ad_break_messages import AdBreak from .types.ad_break_service import ( @@ -51,6 +70,17 @@ ListAdBreaksResponse, UpdateAdBreakRequest, ) +from .types.ad_review_center_ad_enums import AdReviewCenterAdStatusEnum +from .types.ad_review_center_ad_messages import AdReviewCenterAd +from .types.ad_review_center_ad_service import ( + BatchAdReviewCenterAdsOperationMetadata, + BatchAllowAdReviewCenterAdsRequest, + BatchAllowAdReviewCenterAdsResponse, + BatchBlockAdReviewCenterAdsRequest, + BatchBlockAdReviewCenterAdsResponse, + SearchAdReviewCenterAdsRequest, + SearchAdReviewCenterAdsResponse, +) from .types.ad_unit_enums import AdUnitStatusEnum, SmartSizeModeEnum, TargetWindowEnum from .types.ad_unit_messages import AdUnit, AdUnitParent, AdUnitSize, LabelFrequencyCap from .types.ad_unit_service import ( @@ -61,13 +91,51 @@ ListAdUnitsResponse, ) from .types.admanager_error import AdManagerError +from .types.application_messages import Application +from .types.application_service import ( + GetApplicationRequest, + ListApplicationsRequest, + ListApplicationsResponse, +) from .types.applied_label import AppliedLabel +from .types.audience_segment_messages import AudienceSegment +from .types.audience_segment_service import ( + GetAudienceSegmentRequest, + ListAudienceSegmentsRequest, + ListAudienceSegmentsResponse, +) from .types.bandwidth_group_messages import BandwidthGroup from .types.bandwidth_group_service import ( GetBandwidthGroupRequest, ListBandwidthGroupsRequest, ListBandwidthGroupsResponse, ) +from .types.browser_language_messages import BrowserLanguage +from .types.browser_language_service import ( + GetBrowserLanguageRequest, + ListBrowserLanguagesRequest, + ListBrowserLanguagesResponse, +) +from .types.browser_messages import Browser +from .types.browser_service import ( + GetBrowserRequest, + ListBrowsersRequest, + ListBrowsersResponse, +) +from .types.cms_metadata_key_enums import CmsMetadataKeyStatusEnum +from .types.cms_metadata_key_messages import CmsMetadataKey +from .types.cms_metadata_key_service import ( + GetCmsMetadataKeyRequest, + ListCmsMetadataKeysRequest, + ListCmsMetadataKeysResponse, +) +from .types.cms_metadata_value_enums import CmsMetadataValueStatusEnum +from .types.cms_metadata_value_messages import CmsMetadataValue +from .types.cms_metadata_value_service import ( + GetCmsMetadataValueRequest, + ListCmsMetadataValuesRequest, + ListCmsMetadataValuesResponse, +) from .types.company_enums import CompanyCreditStatusEnum, CompanyTypeEnum from .types.company_messages import Company from .types.company_service import ( @@ -75,7 +143,50 @@ ListCompaniesRequest, ListCompaniesResponse, ) +from .types.contact_enums import ContactStatusEnum from .types.contact_messages import Contact +from .types.contact_service import ( + BatchCreateContactsRequest, + BatchCreateContactsResponse, + BatchUpdateContactsRequest, + BatchUpdateContactsResponse, + CreateContactRequest, + GetContactRequest, + ListContactsRequest, + ListContactsResponse, + UpdateContactRequest, +) +from .types.content_bundle_messages import ContentBundle +from .types.content_bundle_service import ( + GetContentBundleRequest, + ListContentBundlesRequest, + ListContentBundlesResponse, +) +from .types.content_label_messages import ContentLabel +from .types.content_label_service import ( + GetContentLabelRequest, + ListContentLabelsRequest, + ListContentLabelsResponse, +) +from .types.content_messages import Content +from .types.content_service import ( + GetContentRequest, + ListContentRequest, + ListContentResponse, +) +from .types.creative_template_enums import ( + CreativeTemplateStatusEnum, + CreativeTemplateTypeEnum, +) +from .types.creative_template_messages import CreativeTemplate, CreativeTemplateVariable +from .types.creative_template_service import ( + GetCreativeTemplateRequest, + ListCreativeTemplatesRequest, + ListCreativeTemplatesResponse, +) +from .types.creative_template_variable_url_type_enum import ( + CreativeTemplateVariableUrlTypeEnum, +) from .types.custom_field_enums import ( CustomFieldDataTypeEnum, CustomFieldEntityTypeEnum, @@ -84,9 +195,19 @@ ) from .types.custom_field_messages import CustomField, CustomFieldOption from .types.custom_field_service import ( + BatchActivateCustomFieldsRequest, + BatchActivateCustomFieldsResponse, + BatchCreateCustomFieldsRequest, + BatchCreateCustomFieldsResponse, + BatchDeactivateCustomFieldsRequest, + BatchDeactivateCustomFieldsResponse, + BatchUpdateCustomFieldsRequest, + BatchUpdateCustomFieldsResponse, + CreateCustomFieldRequest, GetCustomFieldRequest, ListCustomFieldsRequest, ListCustomFieldsResponse, + UpdateCustomFieldRequest, ) from .types.custom_field_value import CustomFieldValue from .types.custom_targeting_key_enums import ( @@ -111,12 +232,24 @@ ListCustomTargetingValuesResponse, ) from .types.deal_buyer_permission_type_enum import DealBuyerPermissionTypeEnum +from .types.device_capability_messages import DeviceCapability +from .types.device_capability_service import ( + GetDeviceCapabilityRequest, + ListDeviceCapabilitiesRequest, + ListDeviceCapabilitiesResponse, +) from .types.device_category_messages import DeviceCategory from .types.device_category_service import ( GetDeviceCategoryRequest, ListDeviceCategoriesRequest, ListDeviceCategoriesResponse, ) +from .types.device_manufacturer_messages import DeviceManufacturer +from .types.device_manufacturer_service import ( + GetDeviceManufacturerRequest, + ListDeviceManufacturersRequest, + ListDeviceManufacturersResponse, +) from .types.early_ad_break_notification_enums import AdBreakStateEnum from .types.entity_signals_mapping_messages import EntitySignalsMapping from .types.entity_signals_mapping_service import ( @@ -131,6 +264,7 @@ UpdateEntitySignalsMappingRequest, ) from .types.environment_type_enum import EnvironmentTypeEnum +from .types.exchange_syndication_product_enum import ExchangeSyndicationProductEnum from .types.frequency_cap import FrequencyCap from .types.geo_target_messages import GeoTarget from .types.geo_target_service import ( @@ -140,6 +274,24 @@ ) from .types.label_messages import Label from .types.live_stream_event_messages import LiveStreamEvent +from .types.mobile_carrier_messages import MobileCarrier +from .types.mobile_carrier_service import ( + GetMobileCarrierRequest, + ListMobileCarriersRequest, + ListMobileCarriersResponse, +) +from .types.mobile_device_messages import MobileDevice +from .types.mobile_device_service import ( + GetMobileDeviceRequest, + ListMobileDevicesRequest, + ListMobileDevicesResponse, +) +from .types.mobile_device_submodel_messages import MobileDeviceSubmodel +from .types.mobile_device_submodel_service import ( + GetMobileDeviceSubmodelRequest, + ListMobileDeviceSubmodelsRequest, + ListMobileDeviceSubmodelsResponse, +) from .types.network_messages import Network from .types.network_service import ( GetNetworkRequest, @@ -164,9 +316,21 @@ from .types.placement_enums import PlacementStatusEnum from .types.placement_messages import Placement from .types.placement_service import ( + BatchActivatePlacementsRequest, + BatchActivatePlacementsResponse, + BatchArchivePlacementsRequest, + BatchArchivePlacementsResponse, + BatchCreatePlacementsRequest, + BatchCreatePlacementsResponse, + BatchDeactivatePlacementsRequest, + BatchDeactivatePlacementsResponse, + BatchUpdatePlacementsRequest, + BatchUpdatePlacementsResponse, + CreatePlacementRequest, GetPlacementRequest, ListPlacementsRequest, ListPlacementsResponse, + UpdatePlacementRequest, ) from .types.private_auction_deal_messages import PrivateAuctionDeal from .types.private_auction_deal_service import ( @@ -191,7 +355,8 @@ ListProgrammaticBuyersRequest, ListProgrammaticBuyersResponse, ) -from .types.report_messages import Report, ReportDefinition, Schedule, ScheduleOptions +from .types.report_definition import ReportDefinition +from .types.report_messages import Report, ReportDataTable, ScheduleOptions from .types.report_service import ( CreateReportRequest, FetchReportResultRowsRequest, @@ -204,23 +369,51 @@ RunReportResponse, UpdateReportRequest, ) +from .types.report_value import ReportValue from .types.request_platform_enum import RequestPlatformEnum from .types.role_enums import RoleStatusEnum from .types.role_messages import Role from .types.role_service import GetRoleRequest, ListRolesRequest, ListRolesResponse +from .types.site_enums import SiteApprovalStatusEnum, SiteDisapprovalReasonEnum +from .types.site_messages import DisapprovalReason, Site +from .types.site_service import ( + BatchCreateSitesRequest, + BatchCreateSitesResponse, + BatchDeactivateSitesRequest, + BatchDeactivateSitesResponse, + BatchSubmitSitesForApprovalRequest, + BatchSubmitSitesForApprovalResponse, + BatchUpdateSitesRequest, + BatchUpdateSitesResponse, + CreateSiteRequest, + GetSiteRequest, + ListSitesRequest, + ListSitesResponse, + UpdateSiteRequest, +) from .types.size import Size from .types.size_type_enum import SizeTypeEnum from .types.targeted_video_bumper_type_enum import TargetedVideoBumperTypeEnum from .types.targeting import ( AdUnitTargeting, + AudienceSegmentTargeting, BandwidthTargeting, + BrowserLanguageTargeting, + BrowserTargeting, + CmsMetadataTargeting, + ContentTargeting, CustomTargeting, CustomTargetingClause, CustomTargetingLiteral, DataSegmentTargeting, + DeviceCapabilityTargeting, DeviceCategoryTargeting, + DeviceManufacturerTargeting, + FirstPartyMobileApplicationTargeting, GeoTargeting, InventoryTargeting, + MobileApplicationTargeting, + MobileCarrierTargeting, OperatingSystemTargeting, RequestPlatformTargeting, Targeting, @@ -236,41 +429,142 @@ ListTaxonomyCategoriesResponse, ) from .types.taxonomy_type_enum import TaxonomyTypeEnum +from .types.team_enums import TeamAccessTypeEnum, TeamStatusEnum from .types.team_messages import Team +from .types.team_service import ( + BatchActivateTeamsRequest, + BatchActivateTeamsResponse, + BatchCreateTeamsRequest, + BatchCreateTeamsResponse, + BatchDeactivateTeamsRequest, + BatchDeactivateTeamsResponse, + BatchUpdateTeamsRequest, + BatchUpdateTeamsResponse, + CreateTeamRequest, + GetTeamRequest, + ListTeamsRequest, + ListTeamsResponse, + UpdateTeamRequest, +) from .types.time_unit_enum import TimeUnitEnum from .types.user_messages import User from .types.user_service import GetUserRequest from .types.video_position_enum import VideoPositionEnum +from .types.web_property import WebProperty __all__ = ( "AdBreak", "AdBreakServiceClient", "AdBreakStateEnum", "AdManagerError", + "AdReviewCenterAd", + "AdReviewCenterAdServiceClient", + "AdReviewCenterAdStatusEnum", "AdUnit", "AdUnitParent", "AdUnitServiceClient", "AdUnitSize", "AdUnitStatusEnum", "AdUnitTargeting", + "Application", + "ApplicationServiceClient", "AppliedLabel", + "AudienceSegment", + "AudienceSegmentServiceClient", + "AudienceSegmentTargeting", "BandwidthGroup", "BandwidthGroupServiceClient", "BandwidthTargeting", + "BatchActivateCustomFieldsRequest", + "BatchActivateCustomFieldsResponse", + "BatchActivatePlacementsRequest", + "BatchActivatePlacementsResponse", + "BatchActivateTeamsRequest", + "BatchActivateTeamsResponse", + "BatchAdReviewCenterAdsOperationMetadata", + "BatchAllowAdReviewCenterAdsRequest", + "BatchAllowAdReviewCenterAdsResponse", + "BatchArchivePlacementsRequest", + "BatchArchivePlacementsResponse", + "BatchBlockAdReviewCenterAdsRequest", + "BatchBlockAdReviewCenterAdsResponse", + "BatchCreateContactsRequest", + "BatchCreateContactsResponse", + "BatchCreateCustomFieldsRequest", + "BatchCreateCustomFieldsResponse", "BatchCreateEntitySignalsMappingsRequest", "BatchCreateEntitySignalsMappingsResponse", + "BatchCreatePlacementsRequest", + "BatchCreatePlacementsResponse", + "BatchCreateSitesRequest", + "BatchCreateSitesResponse", + "BatchCreateTeamsRequest", + "BatchCreateTeamsResponse", + "BatchDeactivateCustomFieldsRequest", + "BatchDeactivateCustomFieldsResponse", + "BatchDeactivatePlacementsRequest", + "BatchDeactivatePlacementsResponse", + "BatchDeactivateSitesRequest", + "BatchDeactivateSitesResponse", + "BatchDeactivateTeamsRequest", + "BatchDeactivateTeamsResponse", + "BatchSubmitSitesForApprovalRequest", + "BatchSubmitSitesForApprovalResponse", + "BatchUpdateContactsRequest", + "BatchUpdateContactsResponse", + "BatchUpdateCustomFieldsRequest", + "BatchUpdateCustomFieldsResponse", "BatchUpdateEntitySignalsMappingsRequest", "BatchUpdateEntitySignalsMappingsResponse", + "BatchUpdatePlacementsRequest", + "BatchUpdatePlacementsResponse", + "BatchUpdateSitesRequest", + "BatchUpdateSitesResponse", + "BatchUpdateTeamsRequest", + "BatchUpdateTeamsResponse", + "Browser", + "BrowserLanguage", + "BrowserLanguageServiceClient", + "BrowserLanguageTargeting", + "BrowserServiceClient", + "BrowserTargeting", + "CmsMetadataKey", + "CmsMetadataKeyServiceClient", + "CmsMetadataKeyStatusEnum", + "CmsMetadataTargeting", + "CmsMetadataValue", + "CmsMetadataValueServiceClient", + "CmsMetadataValueStatusEnum", "Company", "CompanyCreditStatusEnum", "CompanyServiceClient", "CompanyTypeEnum", "Contact", + "ContactServiceClient", + "ContactStatusEnum", + "Content", + "ContentBundle", + "ContentBundleServiceClient", + "ContentLabel", + "ContentLabelServiceClient", + "ContentServiceClient", + "ContentTargeting", "CreateAdBreakRequest", + "CreateContactRequest", + "CreateCustomFieldRequest", "CreateEntitySignalsMappingRequest", + "CreatePlacementRequest", "CreatePrivateAuctionDealRequest", "CreatePrivateAuctionRequest", "CreateReportRequest", + "CreateSiteRequest", + "CreateTeamRequest", + "CreativeTemplate", + "CreativeTemplateServiceClient", + "CreativeTemplateStatusEnum", + "CreativeTemplateTypeEnum", + "CreativeTemplateVariable", + "CreativeTemplateVariableUrlTypeEnum", "CustomField", "CustomFieldDataTypeEnum", "CustomFieldEntityTypeEnum", @@ -294,28 +588,53 @@ "DataSegmentTargeting", "DealBuyerPermissionTypeEnum", "DeleteAdBreakRequest", + "DeviceCapability", + "DeviceCapabilityServiceClient", + "DeviceCapabilityTargeting", "DeviceCategory", "DeviceCategoryServiceClient", "DeviceCategoryTargeting", + "DeviceManufacturer", + "DeviceManufacturerServiceClient", + "DeviceManufacturerTargeting", + "DisapprovalReason", "EntitySignalsMapping", "EntitySignalsMappingServiceClient", "EnvironmentTypeEnum", + "ExchangeSyndicationProductEnum", "FetchReportResultRowsRequest", "FetchReportResultRowsResponse", + "FirstPartyMobileApplicationTargeting", "FrequencyCap", "GeoTarget", "GeoTargetServiceClient", "GeoTargeting", "GetAdBreakRequest", "GetAdUnitRequest", + "GetApplicationRequest", + "GetAudienceSegmentRequest", "GetBandwidthGroupRequest", + "GetBrowserLanguageRequest", + "GetBrowserRequest", + "GetCmsMetadataKeyRequest", + "GetCmsMetadataValueRequest", "GetCompanyRequest", + "GetContactRequest", + "GetContentBundleRequest", + "GetContentLabelRequest", + "GetContentRequest", + "GetCreativeTemplateRequest", "GetCustomFieldRequest", "GetCustomTargetingKeyRequest", "GetCustomTargetingValueRequest", + "GetDeviceCapabilityRequest", "GetDeviceCategoryRequest", + "GetDeviceManufacturerRequest", "GetEntitySignalsMappingRequest", "GetGeoTargetRequest", + "GetMobileCarrierRequest", + "GetMobileDeviceRequest", + "GetMobileDeviceSubmodelRequest", "GetNetworkRequest", "GetOperatingSystemRequest", "GetOperatingSystemVersionRequest", @@ -326,7 +645,9 @@ "GetProgrammaticBuyerRequest", "GetReportRequest", "GetRoleRequest", + "GetSiteRequest", "GetTaxonomyCategoryRequest", + "GetTeamRequest", "GetUserRequest", "InventoryTargeting", "Label", @@ -337,22 +658,54 @@ "ListAdUnitSizesResponse", "ListAdUnitsRequest", "ListAdUnitsResponse", + "ListApplicationsRequest", + "ListApplicationsResponse", + "ListAudienceSegmentsRequest", + "ListAudienceSegmentsResponse", "ListBandwidthGroupsRequest", "ListBandwidthGroupsResponse", + "ListBrowserLanguagesRequest", + "ListBrowserLanguagesResponse", + "ListBrowsersRequest", + "ListBrowsersResponse", + "ListCmsMetadataKeysRequest", + "ListCmsMetadataKeysResponse", + "ListCmsMetadataValuesRequest", + "ListCmsMetadataValuesResponse", "ListCompaniesRequest", "ListCompaniesResponse", + "ListContactsRequest", + "ListContactsResponse", + "ListContentBundlesRequest", + "ListContentBundlesResponse", + "ListContentLabelsRequest", + "ListContentLabelsResponse", + "ListContentRequest", + "ListContentResponse", + "ListCreativeTemplatesRequest", + "ListCreativeTemplatesResponse", "ListCustomFieldsRequest", "ListCustomFieldsResponse", "ListCustomTargetingKeysRequest", "ListCustomTargetingKeysResponse", "ListCustomTargetingValuesRequest", "ListCustomTargetingValuesResponse", + "ListDeviceCapabilitiesRequest", + "ListDeviceCapabilitiesResponse", "ListDeviceCategoriesRequest", "ListDeviceCategoriesResponse", + "ListDeviceManufacturersRequest", + "ListDeviceManufacturersResponse", "ListEntitySignalsMappingsRequest", "ListEntitySignalsMappingsResponse", "ListGeoTargetsRequest", "ListGeoTargetsResponse", + "ListMobileCarriersRequest", + "ListMobileCarriersResponse", + "ListMobileDeviceSubmodelsRequest", + "ListMobileDeviceSubmodelsResponse", + "ListMobileDevicesRequest", + "ListMobileDevicesResponse", "ListNetworksRequest", "ListNetworksResponse", "ListOperatingSystemVersionsRequest", @@ -373,9 +726,21 @@ "ListReportsResponse", "ListRolesRequest", "ListRolesResponse", + "ListSitesRequest", + "ListSitesResponse", "ListTaxonomyCategoriesRequest", "ListTaxonomyCategoriesResponse", + "ListTeamsRequest", + "ListTeamsResponse", "LiveStreamEvent", + "MobileApplicationTargeting", + "MobileCarrier", + "MobileCarrierServiceClient", + "MobileCarrierTargeting", + "MobileDevice", + "MobileDeviceServiceClient", + "MobileDeviceSubmodel", + "MobileDeviceSubmodelServiceClient", "Network", "NetworkServiceClient", "OperatingSystem", @@ -397,8 +762,10 @@ "ProgrammaticBuyer", "ProgrammaticBuyerServiceClient", "Report", + "ReportDataTable", "ReportDefinition", "ReportServiceClient", + "ReportValue", "RequestPlatformEnum", "RequestPlatformTargeting", "Role", @@ -407,8 +774,13 @@ "RunReportMetadata", "RunReportRequest", "RunReportResponse", - "Schedule", "ScheduleOptions", + "SearchAdReviewCenterAdsRequest", + "SearchAdReviewCenterAdsResponse", + "Site", + "SiteApprovalStatusEnum", + "SiteDisapprovalReasonEnum", + "SiteServiceClient", "Size", "SizeTypeEnum", "SmartSizeModeEnum", @@ -419,17 +791,26 @@ "TaxonomyCategoryServiceClient", "TaxonomyTypeEnum", "Team", + "TeamAccessTypeEnum", + "TeamServiceClient", + "TeamStatusEnum", "TechnologyTargeting", "TimeUnitEnum", "UpdateAdBreakRequest", + "UpdateContactRequest", + "UpdateCustomFieldRequest", "UpdateEntitySignalsMappingRequest", + "UpdatePlacementRequest", "UpdatePrivateAuctionDealRequest", "UpdatePrivateAuctionRequest", "UpdateReportRequest", + "UpdateSiteRequest", + "UpdateTeamRequest", "User", "UserDomainTargeting", "UserServiceClient", "VideoPosition", "VideoPositionEnum", "VideoPositionTargeting", + "WebProperty", ) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/gapic_metadata.json b/packages/google-ads-admanager/google/ads/admanager_v1/gapic_metadata.json index 19d842846ad2..daa0d4b46c77 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/gapic_metadata.json +++ b/packages/google-ads-admanager/google/ads/admanager_v1/gapic_metadata.json @@ -39,6 +39,30 @@ } } }, + "AdReviewCenterAdService": { + "clients": { + "rest": { + "libraryClient": "AdReviewCenterAdServiceClient", + "rpcs": { + "BatchAllowAdReviewCenterAds": { + "methods": [ + "batch_allow_ad_review_center_ads" + ] + }, + "BatchBlockAdReviewCenterAds": { + "methods": [ + "batch_block_ad_review_center_ads" + ] + }, + "SearchAdReviewCenterAds": { + "methods": [ + "search_ad_review_center_ads" + ] + } + } + } + } + }, "AdUnitService": { "clients": { "rest": { @@ -63,6 +87,44 @@ } } }, + "ApplicationService": { + "clients": { + "rest": { + "libraryClient": "ApplicationServiceClient", + "rpcs": { + "GetApplication": { + "methods": [ + "get_application" + ] + }, + "ListApplications": { + "methods": [ + "list_applications" + ] + } + } + } + } + }, + "AudienceSegmentService": { + "clients": { + "rest": { + "libraryClient": "AudienceSegmentServiceClient", + "rpcs": { + "GetAudienceSegment": { + "methods": [ + "get_audience_segment" + ] + }, + "ListAudienceSegments": { + "methods": [ + "list_audience_segments" + ] + } + } + } + } + }, "BandwidthGroupService": { "clients": { "rest": { @@ -82,6 +144,82 @@ } } }, + "BrowserLanguageService": { + "clients": { + "rest": { + "libraryClient": "BrowserLanguageServiceClient", + "rpcs": { + "GetBrowserLanguage": { + "methods": [ + "get_browser_language" + ] + }, + "ListBrowserLanguages": { + "methods": [ + "list_browser_languages" + ] + } + } + } + } + }, + "BrowserService": { + "clients": { + "rest": { + "libraryClient": "BrowserServiceClient", + "rpcs": { + "GetBrowser": { + "methods": [ + "get_browser" + ] + }, + "ListBrowsers": { + "methods": [ + "list_browsers" + ] + } + } + } + } + }, + "CmsMetadataKeyService": { + "clients": { + "rest": { + "libraryClient": "CmsMetadataKeyServiceClient", + "rpcs": { + "GetCmsMetadataKey": { + "methods": [ + "get_cms_metadata_key" + ] + }, + "ListCmsMetadataKeys": { + "methods": [ + "list_cms_metadata_keys" + ] + } + } + } + } + }, + "CmsMetadataValueService": { + "clients": { + "rest": { + "libraryClient": "CmsMetadataValueServiceClient", + "rpcs": { + "GetCmsMetadataValue": { + "methods": [ + "get_cms_metadata_value" + ] + }, + "ListCmsMetadataValues": { + "methods": [ + "list_cms_metadata_values" + ] + } + } + } + } + }, "CompanyService": { "clients": { "rest": { @@ -101,11 +239,151 @@ } } }, + "ContactService": { + "clients": { + "rest": { + "libraryClient": "ContactServiceClient", + "rpcs": { + "BatchCreateContacts": { + "methods": [ + "batch_create_contacts" + ] + }, + "BatchUpdateContacts": { + "methods": [ + "batch_update_contacts" + ] + }, + "CreateContact": { + "methods": [ + "create_contact" + ] + }, + "GetContact": { + "methods": [ + "get_contact" + ] + }, + "ListContacts": { + "methods": [ + "list_contacts" + ] + }, + "UpdateContact": { + "methods": [ + "update_contact" + ] + } + } + } + } + }, + "ContentBundleService": { + "clients": { + "rest": { + "libraryClient": "ContentBundleServiceClient", + "rpcs": { + "GetContentBundle": { + "methods": [ + "get_content_bundle" + ] + }, + "ListContentBundles": { + "methods": [ + "list_content_bundles" + ] + } + } + } + } + }, + "ContentLabelService": { + "clients": { + "rest": { + "libraryClient": "ContentLabelServiceClient", + "rpcs": { + "GetContentLabel": { + "methods": [ + "get_content_label" + ] + }, + "ListContentLabels": { + "methods": [ + "list_content_labels" + ] + } + } + } + } + }, + "ContentService": { + "clients": { + "rest": { + "libraryClient": "ContentServiceClient", + "rpcs": { + "GetContent": { + "methods": [ + "get_content" + ] + }, + "ListContent": { + "methods": [ + "list_content" + ] + } + } + } + } + }, + "CreativeTemplateService": { + "clients": { + "rest": { + "libraryClient": "CreativeTemplateServiceClient", + "rpcs": { + "GetCreativeTemplate": { + "methods": [ + "get_creative_template" + ] + }, + "ListCreativeTemplates": { + "methods": [ + "list_creative_templates" + ] + } + } + } + } + }, "CustomFieldService": { "clients": { "rest": { "libraryClient": "CustomFieldServiceClient", "rpcs": { + "BatchActivateCustomFields": { + "methods": [ + "batch_activate_custom_fields" + ] + }, + "BatchCreateCustomFields": { + "methods": [ + "batch_create_custom_fields" + ] + }, + "BatchDeactivateCustomFields": { + "methods": [ + "batch_deactivate_custom_fields" + ] + }, + "BatchUpdateCustomFields": { + "methods": [ + "batch_update_custom_fields" + ] + }, + "CreateCustomField": { + "methods": [ + "create_custom_field" + ] + }, "GetCustomField": { "methods": [ "get_custom_field" @@ -115,6 +393,11 @@ "methods": [ "list_custom_fields" ] + }, + "UpdateCustomField": { + "methods": [ + "update_custom_field" + ] } } } @@ -158,6 +441,25 @@ } } }, + "DeviceCapabilityService": { + "clients": { + "rest": { + "libraryClient": "DeviceCapabilityServiceClient", + "rpcs": { + "GetDeviceCapability": { + "methods": [ + "get_device_capability" + ] + }, + "ListDeviceCapabilities": { + "methods": [ + "list_device_capabilities" + ] + } + } + } + } + }, "DeviceCategoryService": { "clients": { "rest": { @@ -177,6 +479,25 @@ } } }, + "DeviceManufacturerService": { + "clients": { + "rest": { + "libraryClient": "DeviceManufacturerServiceClient", + "rpcs": { + "GetDeviceManufacturer": { + "methods": [ + "get_device_manufacturer" + ] + }, + "ListDeviceManufacturers": { + "methods": [ + "list_device_manufacturers" + ] + } + } + } + } + }, "EntitySignalsMappingService": { "clients": { "rest": { @@ -235,6 +556,63 @@ } } }, + "MobileCarrierService": { + "clients": { + "rest": { + "libraryClient": "MobileCarrierServiceClient", + "rpcs": { + "GetMobileCarrier": { + "methods": [ + "get_mobile_carrier" + ] + }, + "ListMobileCarriers": { + "methods": [ + "list_mobile_carriers" + ] + } + } + } + } + }, + "MobileDeviceService": { + "clients": { + "rest": { + "libraryClient": "MobileDeviceServiceClient", + "rpcs": { + "GetMobileDevice": { + "methods": [ + "get_mobile_device" + ] + }, + "ListMobileDevices": { + "methods": [ + "list_mobile_devices" + ] + } + } + } + } + }, + "MobileDeviceSubmodelService": { + "clients": { + "rest": { + "libraryClient": "MobileDeviceSubmodelServiceClient", + "rpcs": { + "GetMobileDeviceSubmodel": { + "methods": [ + "get_mobile_device_submodel" + ] + }, + "ListMobileDeviceSubmodels": { + "methods": [ + "list_mobile_device_submodels" + ] + } + } + } + } + }, "NetworkService": { "clients": { "rest": { @@ -316,6 +694,36 @@ "rest": { "libraryClient": "PlacementServiceClient", "rpcs": { + "BatchActivatePlacements": { + "methods": [ + "batch_activate_placements" + ] + }, + "BatchArchivePlacements": { + "methods": [ + "batch_archive_placements" + ] + }, + "BatchCreatePlacements": { + "methods": [ + "batch_create_placements" + ] + }, + "BatchDeactivatePlacements": { + "methods": [ + "batch_deactivate_placements" + ] + }, + "BatchUpdatePlacements": { + "methods": [ + "batch_update_placements" + ] + }, + "CreatePlacement": { + "methods": [ + "create_placement" + ] + }, "GetPlacement": { "methods": [ "get_placement" @@ -325,6 +733,11 @@ "methods": [ "list_placements" ] + }, + "UpdatePlacement": { + "methods": [ + "update_placement" + ] } } } @@ -465,6 +878,55 @@ } } }, + "SiteService": { + "clients": { + "rest": { + "libraryClient": "SiteServiceClient", + "rpcs": { + "BatchCreateSites": { + "methods": [ + "batch_create_sites" + ] + }, + "BatchDeactivateSites": { + "methods": [ + "batch_deactivate_sites" + ] + }, + "BatchSubmitSitesForApproval": { + "methods": [ + "batch_submit_sites_for_approval" + ] + }, + "BatchUpdateSites": { + "methods": [ + "batch_update_sites" + ] + }, + "CreateSite": { + "methods": [ + "create_site" + ] + }, + "GetSite": { + "methods": [ + "get_site" + ] + }, + "ListSites": { + "methods": [ + "list_sites" + ] + }, + "UpdateSite": { + "methods": [ + "update_site" + ] + } + } + } + } + }, "TaxonomyCategoryService": { "clients": { "rest": { @@ -484,6 +946,55 @@ } } }, + "TeamService": { + "clients": { + "rest": { + "libraryClient": "TeamServiceClient", + "rpcs": { + "BatchActivateTeams": { + "methods": [ + "batch_activate_teams" + ] + }, + "BatchCreateTeams": { + "methods": [ + "batch_create_teams" + ] + }, + "BatchDeactivateTeams": { + "methods": [ + "batch_deactivate_teams" + ] + }, + "BatchUpdateTeams": { + "methods": [ + "batch_update_teams" + ] + }, + "CreateTeam": { + "methods": [ + "create_team" + ] + }, + "GetTeam": { + "methods": [ + "get_team" + ] + }, + "ListTeams": { + "methods": [ + "list_teams" + ] + }, + "UpdateTeam": { + "methods": [ + "update_team" + ] + } + } + } + } + }, "UserService": { "clients": { "rest": { diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/__init__.py new file mode 100644 index 000000000000..7f2c85606d3d --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AdReviewCenterAdServiceClient + +__all__ = ("AdReviewCenterAdServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/client.py new file mode 100644 index 000000000000..8616fe55a85f --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/client.py @@ -0,0 +1,1269 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +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.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version + +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.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from google.ads.admanager_v1.services.ad_review_center_ad_service import pagers +from google.ads.admanager_v1.types import ( + ad_review_center_ad_messages, + ad_review_center_ad_service, +) + +from .transports.base import DEFAULT_CLIENT_INFO, AdReviewCenterAdServiceTransport +from .transports.rest import AdReviewCenterAdServiceRestTransport + + +class AdReviewCenterAdServiceClientMeta(type): + """Metaclass for the AdReviewCenterAdService 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[AdReviewCenterAdServiceTransport]] + _transport_registry["rest"] = AdReviewCenterAdServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AdReviewCenterAdServiceTransport]: + """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 AdReviewCenterAdServiceClient(metaclass=AdReviewCenterAdServiceClientMeta): + """Provides methods for handling AdReviewCenterAd objects.""" + + @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 = "admanager.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "admanager.{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: + AdReviewCenterAdServiceClient: 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: + AdReviewCenterAdServiceClient: 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) -> AdReviewCenterAdServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdReviewCenterAdServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def ad_review_center_ad_path( + network_code: str, + web_property_code: str, + ad_review_center_ad: str, + ) -> str: + """Returns a fully-qualified ad_review_center_ad string.""" + return "networks/{network_code}/webProperties/{web_property_code}/adReviewCenterAds/{ad_review_center_ad}".format( + network_code=network_code, + web_property_code=web_property_code, + ad_review_center_ad=ad_review_center_ad, + ) + + @staticmethod + def parse_ad_review_center_ad_path(path: str) -> Dict[str, str]: + """Parses a ad_review_center_ad path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/webProperties/(?P.+?)/adReviewCenterAds/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def web_property_path( + network_code: str, + web_property: str, + ) -> str: + """Returns a fully-qualified web_property string.""" + return "networks/{network_code}/webProperties/{web_property}".format( + network_code=network_code, + web_property=web_property, + ) + + @staticmethod + def parse_web_property_path(path: str) -> Dict[str, str]: + """Parses a web_property path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/webProperties/(?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 = AdReviewCenterAdServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AdReviewCenterAdServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + AdReviewCenterAdServiceClient._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 = AdReviewCenterAdServiceClient._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, + AdReviewCenterAdServiceTransport, + Callable[..., AdReviewCenterAdServiceTransport], + ] + ] = 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 review center 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,AdReviewCenterAdServiceTransport,Callable[..., AdReviewCenterAdServiceTransport]]]): + 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 AdReviewCenterAdServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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, + ) = AdReviewCenterAdServiceClient._read_environment_variables() + self._client_cert_source = ( + AdReviewCenterAdServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = AdReviewCenterAdServiceClient._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, AdReviewCenterAdServiceTransport) + if transport_provided: + # transport is a AdReviewCenterAdServiceTransport 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(AdReviewCenterAdServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AdReviewCenterAdServiceClient._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[AdReviewCenterAdServiceTransport], + Callable[..., AdReviewCenterAdServiceTransport], + ] = ( + AdReviewCenterAdServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., AdReviewCenterAdServiceTransport], 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.admanager_v1.AdReviewCenterAdServiceClient`.", + extra={ + "serviceName": "google.ads.admanager.v1.AdReviewCenterAdService", + "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.admanager.v1.AdReviewCenterAdService", + "credentialsType": None, + }, + ) + + def search_ad_review_center_ads( + self, + request: Optional[ + Union[ad_review_center_ad_service.SearchAdReviewCenterAdsRequest, dict] + ] = None, + *, + parent: 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.SearchAdReviewCenterAdsPager: + r"""API to search for AdReviewCenterAds. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_search_ad_review_center_ads(): + # Create a client + client = admanager_v1.AdReviewCenterAdServiceClient() + + # Initialize request argument(s) + request = admanager_v1.SearchAdReviewCenterAdsRequest( + parent="parent_value", + status="UNREVIEWED", + ) + + # Make the request + page_result = client.search_ad_review_center_ads(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.SearchAdReviewCenterAdsRequest, dict]): + The request object. Request object for ``SearchAdReviewCenterAds`` method. + parent (str): + Required. The parent, which owns this collection of + AdReviewCenterAds. Format: + networks/{network_code}/webProperties/{web_property_code} + + Since a network can only have a single web property of + each ``ExchangeSyndicationProduct``, you can use the + ``ExchangeSyndicationProduct`` as an alias for the web + property code: + + ``networks/{network_code}/webProperties/display`` + + ``networks/{network_code}/webProperties/videoAndAudio`` + + ``networks/{network_code}/webProperties/mobileApp`` + + ``networks/{network_code}/webProperties/games`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.services.ad_review_center_ad_service.pagers.SearchAdReviewCenterAdsPager: + Response object for SearchAdReviewCenterAds method. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request 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_review_center_ad_service.SearchAdReviewCenterAdsRequest + ): + request = ad_review_center_ad_service.SearchAdReviewCenterAdsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.search_ad_review_center_ads + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.SearchAdReviewCenterAdsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def batch_allow_ad_review_center_ads( + self, + request: Optional[ + Union[ad_review_center_ad_service.BatchAllowAdReviewCenterAdsRequest, dict] + ] = None, + *, + parent: 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"""API to batch allow AdReviewCenterAds. + This method supports partial success. Some operations + may succeed while others fail. Callers should check the + failedRequests field in the response to determine which + operations failed. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_batch_allow_ad_review_center_ads(): + # Create a client + client = admanager_v1.AdReviewCenterAdServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchAllowAdReviewCenterAdsRequest( + parent="parent_value", + names=['names_value1', 'names_value2'], + ) + + # Make the request + operation = client.batch_allow_ad_review_center_ads(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.BatchAllowAdReviewCenterAdsRequest, dict]): + The request object. Request object for ``BatchAllowAdReviewCenterAds`` + method. + parent (str): + Required. The parent, which owns this collection of + AdReviewCenterAds. Format: + networks/{network_code}/webProperties/{web_property_code} + + Since a network can only have a single web property of + each ``ExchangeSyndicationProduct``, you can use the + ``ExchangeSyndicationProduct`` as an alias for the web + property code: + + ``networks/{network_code}/webProperties/display`` + + ``networks/{network_code}/webProperties/videoAndAudio`` + + ``networks/{network_code}/webProperties/mobileApp`` + + ``networks/{network_code}/webProperties/games`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value 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.ads.admanager_v1.types.BatchAllowAdReviewCenterAdsResponse` + Response object for BatchAllowAdReviewCenterAds method. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request 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_review_center_ad_service.BatchAllowAdReviewCenterAdsRequest + ): + request = ad_review_center_ad_service.BatchAllowAdReviewCenterAdsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.batch_allow_ad_review_center_ads + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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, + ad_review_center_ad_service.BatchAllowAdReviewCenterAdsResponse, + metadata_type=ad_review_center_ad_service.BatchAdReviewCenterAdsOperationMetadata, + ) + + # Done; return the response. + return response + + def batch_block_ad_review_center_ads( + self, + request: Optional[ + Union[ad_review_center_ad_service.BatchBlockAdReviewCenterAdsRequest, dict] + ] = None, + *, + parent: 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"""API to batch block AdReviewCenterAds. + This method supports partial success. Some operations + may succeed while others fail. Callers should check the + failedRequests field in the response to determine which + operations failed. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_batch_block_ad_review_center_ads(): + # Create a client + client = admanager_v1.AdReviewCenterAdServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchBlockAdReviewCenterAdsRequest( + parent="parent_value", + names=['names_value1', 'names_value2'], + ) + + # Make the request + operation = client.batch_block_ad_review_center_ads(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.BatchBlockAdReviewCenterAdsRequest, dict]): + The request object. Request object for ``BatchBlockAdReviewCenterAds`` + method. + parent (str): + Required. The parent, which owns this collection of + AdReviewCenterAds. Format: + networks/{network_code}/webProperties/{web_property_code} + + Since a network can only have a single web property of + each ``ExchangeSyndicationProduct``, you can use the + ``ExchangeSyndicationProduct`` as an alias for the web + property code: + + ``networks/{network_code}/webProperties/display`` + + ``networks/{network_code}/webProperties/videoAndAudio`` + + ``networks/{network_code}/webProperties/mobileApp`` + + ``networks/{network_code}/webProperties/games`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value 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.ads.admanager_v1.types.BatchBlockAdReviewCenterAdsResponse` + Response object for BatchBlockAdReviewCenterAds method. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request 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_review_center_ad_service.BatchBlockAdReviewCenterAdsRequest + ): + request = ad_review_center_ad_service.BatchBlockAdReviewCenterAdsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.batch_block_ad_review_center_ads + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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, + ad_review_center_ad_service.BatchBlockAdReviewCenterAdsResponse, + metadata_type=ad_review_center_ad_service.BatchAdReviewCenterAdsOperationMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AdReviewCenterAdServiceClient": + 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() + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AdReviewCenterAdServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/pagers.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/pagers.py new file mode 100644 index 000000000000..5b7d3e65cde6 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/pagers.py @@ -0,0 +1,126 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +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 + +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.admanager_v1.types import ( + ad_review_center_ad_messages, + ad_review_center_ad_service, +) + + +class SearchAdReviewCenterAdsPager: + """A pager for iterating through ``search_ad_review_center_ads`` requests. + + This class thinly wraps an initial + :class:`google.ads.admanager_v1.types.SearchAdReviewCenterAdsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``ad_review_center_ads`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``SearchAdReviewCenterAds`` requests and continue to iterate + through the ``ad_review_center_ads`` field on the + corresponding responses. + + All the usual :class:`google.ads.admanager_v1.types.SearchAdReviewCenterAdsResponse` + 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[ + ..., ad_review_center_ad_service.SearchAdReviewCenterAdsResponse + ], + request: ad_review_center_ad_service.SearchAdReviewCenterAdsRequest, + response: ad_review_center_ad_service.SearchAdReviewCenterAdsResponse, + *, + 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.admanager_v1.types.SearchAdReviewCenterAdsRequest): + The initial request object. + response (google.ads.admanager_v1.types.SearchAdReviewCenterAdsResponse): + 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 = ad_review_center_ad_service.SearchAdReviewCenterAdsRequest( + 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[ad_review_center_ad_service.SearchAdReviewCenterAdsResponse]: + 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[ad_review_center_ad_messages.AdReviewCenterAd]: + for page in self.pages: + yield from page.ad_review_center_ads + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/transports/README.rst b/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/transports/README.rst new file mode 100644 index 000000000000..6899571aa192 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`AdReviewCenterAdServiceTransport` is the ABC for all transports. +- public child `AdReviewCenterAdServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `AdReviewCenterAdServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseAdReviewCenterAdServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `AdReviewCenterAdServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/transports/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/transports/__init__.py new file mode 100644 index 000000000000..91d81f66f8c2 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/transports/__init__.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 typing import Dict, Type + +from .base import AdReviewCenterAdServiceTransport +from .rest import ( + AdReviewCenterAdServiceRestInterceptor, + AdReviewCenterAdServiceRestTransport, +) + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AdReviewCenterAdServiceTransport]] +_transport_registry["rest"] = AdReviewCenterAdServiceRestTransport + +__all__ = ( + "AdReviewCenterAdServiceTransport", + "AdReviewCenterAdServiceRestTransport", + "AdReviewCenterAdServiceRestInterceptor", +) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/transports/base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/transports/base.py new file mode 100644 index 000000000000..358bed01c7a7 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_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, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, operations_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version +from google.ads.admanager_v1.types import ad_review_center_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 AdReviewCenterAdServiceTransport(abc.ABC): + """Abstract transport class for AdReviewCenterAdService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/admanager",) + + DEFAULT_HOST: str = "admanager.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: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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_ad_review_center_ads: gapic_v1.method.wrap_method( + self.search_ad_review_center_ads, + default_timeout=None, + client_info=client_info, + ), + self.batch_allow_ad_review_center_ads: gapic_v1.method.wrap_method( + self.batch_allow_ad_review_center_ads, + default_timeout=None, + client_info=client_info, + ), + self.batch_block_ad_review_center_ads: gapic_v1.method.wrap_method( + self.batch_block_ad_review_center_ads, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + 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 search_ad_review_center_ads( + self, + ) -> Callable[ + [ad_review_center_ad_service.SearchAdReviewCenterAdsRequest], + Union[ + ad_review_center_ad_service.SearchAdReviewCenterAdsResponse, + Awaitable[ad_review_center_ad_service.SearchAdReviewCenterAdsResponse], + ], + ]: + raise NotImplementedError() + + @property + def batch_allow_ad_review_center_ads( + self, + ) -> Callable[ + [ad_review_center_ad_service.BatchAllowAdReviewCenterAdsRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def batch_block_ad_review_center_ads( + self, + ) -> Callable[ + [ad_review_center_ad_service.BatchBlockAdReviewCenterAdsRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AdReviewCenterAdServiceTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/transports/rest.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/transports/rest.py new file mode 100644 index 000000000000..6acb0b61629d --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/transports/rest.py @@ -0,0 +1,1060 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import gapic_v1, operations_v1, rest_helpers, rest_streaming +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.ads.admanager_v1.types import ad_review_center_ad_service + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseAdReviewCenterAdServiceRestTransport + +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 = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AdReviewCenterAdServiceRestInterceptor: + """Interceptor for AdReviewCenterAdService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the AdReviewCenterAdServiceRestTransport. + + .. code-block:: python + class MyCustomAdReviewCenterAdServiceInterceptor(AdReviewCenterAdServiceRestInterceptor): + def pre_batch_allow_ad_review_center_ads(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_allow_ad_review_center_ads(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_block_ad_review_center_ads(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_block_ad_review_center_ads(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_search_ad_review_center_ads(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_search_ad_review_center_ads(self, response): + logging.log(f"Received response: {response}") + return response + + transport = AdReviewCenterAdServiceRestTransport(interceptor=MyCustomAdReviewCenterAdServiceInterceptor()) + client = AdReviewCenterAdServiceClient(transport=transport) + + + """ + + def pre_batch_allow_ad_review_center_ads( + self, + request: ad_review_center_ad_service.BatchAllowAdReviewCenterAdsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + ad_review_center_ad_service.BatchAllowAdReviewCenterAdsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for batch_allow_ad_review_center_ads + + Override in a subclass to manipulate the request or metadata + before they are sent to the AdReviewCenterAdService server. + """ + return request, metadata + + def post_batch_allow_ad_review_center_ads( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for batch_allow_ad_review_center_ads + + DEPRECATED. Please use the `post_batch_allow_ad_review_center_ads_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the AdReviewCenterAdService server but before + it is returned to user code. This `post_batch_allow_ad_review_center_ads` interceptor runs + before the `post_batch_allow_ad_review_center_ads_with_metadata` interceptor. + """ + return response + + def post_batch_allow_ad_review_center_ads_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_allow_ad_review_center_ads + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the AdReviewCenterAdService server but before it is returned to user code. + + We recommend only using this `post_batch_allow_ad_review_center_ads_with_metadata` + interceptor in new development instead of the `post_batch_allow_ad_review_center_ads` interceptor. + When both interceptors are used, this `post_batch_allow_ad_review_center_ads_with_metadata` interceptor runs after the + `post_batch_allow_ad_review_center_ads` interceptor. The (possibly modified) response returned by + `post_batch_allow_ad_review_center_ads` will be passed to + `post_batch_allow_ad_review_center_ads_with_metadata`. + """ + return response, metadata + + def pre_batch_block_ad_review_center_ads( + self, + request: ad_review_center_ad_service.BatchBlockAdReviewCenterAdsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + ad_review_center_ad_service.BatchBlockAdReviewCenterAdsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for batch_block_ad_review_center_ads + + Override in a subclass to manipulate the request or metadata + before they are sent to the AdReviewCenterAdService server. + """ + return request, metadata + + def post_batch_block_ad_review_center_ads( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for batch_block_ad_review_center_ads + + DEPRECATED. Please use the `post_batch_block_ad_review_center_ads_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the AdReviewCenterAdService server but before + it is returned to user code. This `post_batch_block_ad_review_center_ads` interceptor runs + before the `post_batch_block_ad_review_center_ads_with_metadata` interceptor. + """ + return response + + def post_batch_block_ad_review_center_ads_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_block_ad_review_center_ads + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the AdReviewCenterAdService server but before it is returned to user code. + + We recommend only using this `post_batch_block_ad_review_center_ads_with_metadata` + interceptor in new development instead of the `post_batch_block_ad_review_center_ads` interceptor. + When both interceptors are used, this `post_batch_block_ad_review_center_ads_with_metadata` interceptor runs after the + `post_batch_block_ad_review_center_ads` interceptor. The (possibly modified) response returned by + `post_batch_block_ad_review_center_ads` will be passed to + `post_batch_block_ad_review_center_ads_with_metadata`. + """ + return response, metadata + + def pre_search_ad_review_center_ads( + self, + request: ad_review_center_ad_service.SearchAdReviewCenterAdsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + ad_review_center_ad_service.SearchAdReviewCenterAdsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for search_ad_review_center_ads + + Override in a subclass to manipulate the request or metadata + before they are sent to the AdReviewCenterAdService server. + """ + return request, metadata + + def post_search_ad_review_center_ads( + self, response: ad_review_center_ad_service.SearchAdReviewCenterAdsResponse + ) -> ad_review_center_ad_service.SearchAdReviewCenterAdsResponse: + """Post-rpc interceptor for search_ad_review_center_ads + + DEPRECATED. Please use the `post_search_ad_review_center_ads_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the AdReviewCenterAdService server but before + it is returned to user code. This `post_search_ad_review_center_ads` interceptor runs + before the `post_search_ad_review_center_ads_with_metadata` interceptor. + """ + return response + + def post_search_ad_review_center_ads_with_metadata( + self, + response: ad_review_center_ad_service.SearchAdReviewCenterAdsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + ad_review_center_ad_service.SearchAdReviewCenterAdsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for search_ad_review_center_ads + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the AdReviewCenterAdService server but before it is returned to user code. + + We recommend only using this `post_search_ad_review_center_ads_with_metadata` + interceptor in new development instead of the `post_search_ad_review_center_ads` interceptor. + When both interceptors are used, this `post_search_ad_review_center_ads_with_metadata` interceptor runs after the + `post_search_ad_review_center_ads` interceptor. The (possibly modified) response returned by + `post_search_ad_review_center_ads` will be passed to + `post_search_ad_review_center_ads_with_metadata`. + """ + return response, metadata + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the AdReviewCenterAdService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the AdReviewCenterAdService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class AdReviewCenterAdServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: AdReviewCenterAdServiceRestInterceptor + + +class AdReviewCenterAdServiceRestTransport(_BaseAdReviewCenterAdServiceRestTransport): + """REST backend synchronous transport for AdReviewCenterAdService. + + Provides methods for handling AdReviewCenterAd objects. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[AdReviewCenterAdServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or AdReviewCenterAdServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + @property + def operations_client(self) -> operations_v1.AbstractOperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Only create a new client if we do not already have one. + if self._operations_client is None: + http_options: Dict[str, List[Dict[str, str]]] = { + "google.longrunning.Operations.GetOperation": [ + { + "method": "get", + "uri": "/v1/{name=networks/*/operations/reports/runs/*}", + }, + ], + } + + rest_transport = operations_v1.OperationsRestTransport( + host=self._host, + # use the credentials which are saved + credentials=self._credentials, + scopes=self._scopes, + http_options=http_options, + path_prefix="v1", + ) + + self._operations_client = operations_v1.AbstractOperationsClient( + transport=rest_transport + ) + + # Return the client from cache. + return self._operations_client + + class _BatchAllowAdReviewCenterAds( + _BaseAdReviewCenterAdServiceRestTransport._BaseBatchAllowAdReviewCenterAds, + AdReviewCenterAdServiceRestStub, + ): + def __hash__(self): + return hash( + "AdReviewCenterAdServiceRestTransport.BatchAllowAdReviewCenterAds" + ) + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: ad_review_center_ad_service.BatchAllowAdReviewCenterAdsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the batch allow ad review + center ads method over HTTP. + + Args: + request (~.ad_review_center_ad_service.BatchAllowAdReviewCenterAdsRequest): + The request object. Request object for ``BatchAllowAdReviewCenterAds`` + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = ( + _BaseAdReviewCenterAdServiceRestTransport._BaseBatchAllowAdReviewCenterAds._get_http_options() + ) + + request, metadata = self._interceptor.pre_batch_allow_ad_review_center_ads( + request, metadata + ) + transcoded_request = _BaseAdReviewCenterAdServiceRestTransport._BaseBatchAllowAdReviewCenterAds._get_transcoded_request( + http_options, request + ) + + body = _BaseAdReviewCenterAdServiceRestTransport._BaseBatchAllowAdReviewCenterAds._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseAdReviewCenterAdServiceRestTransport._BaseBatchAllowAdReviewCenterAds._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.AdReviewCenterAdServiceClient.BatchAllowAdReviewCenterAds", + extra={ + "serviceName": "google.ads.admanager.v1.AdReviewCenterAdService", + "rpcName": "BatchAllowAdReviewCenterAds", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = AdReviewCenterAdServiceRestTransport._BatchAllowAdReviewCenterAds._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_allow_ad_review_center_ads(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_batch_allow_ad_review_center_ads_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.AdReviewCenterAdServiceClient.batch_allow_ad_review_center_ads", + extra={ + "serviceName": "google.ads.admanager.v1.AdReviewCenterAdService", + "rpcName": "BatchAllowAdReviewCenterAds", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _BatchBlockAdReviewCenterAds( + _BaseAdReviewCenterAdServiceRestTransport._BaseBatchBlockAdReviewCenterAds, + AdReviewCenterAdServiceRestStub, + ): + def __hash__(self): + return hash( + "AdReviewCenterAdServiceRestTransport.BatchBlockAdReviewCenterAds" + ) + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: ad_review_center_ad_service.BatchBlockAdReviewCenterAdsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the batch block ad review + center ads method over HTTP. + + Args: + request (~.ad_review_center_ad_service.BatchBlockAdReviewCenterAdsRequest): + The request object. Request object for ``BatchBlockAdReviewCenterAds`` + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = ( + _BaseAdReviewCenterAdServiceRestTransport._BaseBatchBlockAdReviewCenterAds._get_http_options() + ) + + request, metadata = self._interceptor.pre_batch_block_ad_review_center_ads( + request, metadata + ) + transcoded_request = _BaseAdReviewCenterAdServiceRestTransport._BaseBatchBlockAdReviewCenterAds._get_transcoded_request( + http_options, request + ) + + body = _BaseAdReviewCenterAdServiceRestTransport._BaseBatchBlockAdReviewCenterAds._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseAdReviewCenterAdServiceRestTransport._BaseBatchBlockAdReviewCenterAds._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.AdReviewCenterAdServiceClient.BatchBlockAdReviewCenterAds", + extra={ + "serviceName": "google.ads.admanager.v1.AdReviewCenterAdService", + "rpcName": "BatchBlockAdReviewCenterAds", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = AdReviewCenterAdServiceRestTransport._BatchBlockAdReviewCenterAds._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_block_ad_review_center_ads(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_batch_block_ad_review_center_ads_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.AdReviewCenterAdServiceClient.batch_block_ad_review_center_ads", + extra={ + "serviceName": "google.ads.admanager.v1.AdReviewCenterAdService", + "rpcName": "BatchBlockAdReviewCenterAds", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _SearchAdReviewCenterAds( + _BaseAdReviewCenterAdServiceRestTransport._BaseSearchAdReviewCenterAds, + AdReviewCenterAdServiceRestStub, + ): + def __hash__(self): + return hash("AdReviewCenterAdServiceRestTransport.SearchAdReviewCenterAds") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: ad_review_center_ad_service.SearchAdReviewCenterAdsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_review_center_ad_service.SearchAdReviewCenterAdsResponse: + r"""Call the search ad review center + ads method over HTTP. + + Args: + request (~.ad_review_center_ad_service.SearchAdReviewCenterAdsRequest): + The request object. Request object for ``SearchAdReviewCenterAds`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.ad_review_center_ad_service.SearchAdReviewCenterAdsResponse: + Response object for ``SearchAdReviewCenterAds`` method. + """ + + http_options = ( + _BaseAdReviewCenterAdServiceRestTransport._BaseSearchAdReviewCenterAds._get_http_options() + ) + + request, metadata = self._interceptor.pre_search_ad_review_center_ads( + request, metadata + ) + transcoded_request = _BaseAdReviewCenterAdServiceRestTransport._BaseSearchAdReviewCenterAds._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseAdReviewCenterAdServiceRestTransport._BaseSearchAdReviewCenterAds._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.AdReviewCenterAdServiceClient.SearchAdReviewCenterAds", + extra={ + "serviceName": "google.ads.admanager.v1.AdReviewCenterAdService", + "rpcName": "SearchAdReviewCenterAds", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = AdReviewCenterAdServiceRestTransport._SearchAdReviewCenterAds._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = ad_review_center_ad_service.SearchAdReviewCenterAdsResponse() + pb_resp = ad_review_center_ad_service.SearchAdReviewCenterAdsResponse.pb( + resp + ) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_search_ad_review_center_ads(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_search_ad_review_center_ads_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ad_review_center_ad_service.SearchAdReviewCenterAdsResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.AdReviewCenterAdServiceClient.search_ad_review_center_ads", + extra={ + "serviceName": "google.ads.admanager.v1.AdReviewCenterAdService", + "rpcName": "SearchAdReviewCenterAds", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def batch_allow_ad_review_center_ads( + self, + ) -> Callable[ + [ad_review_center_ad_service.BatchAllowAdReviewCenterAdsRequest], + operations_pb2.Operation, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchAllowAdReviewCenterAds(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_block_ad_review_center_ads( + self, + ) -> Callable[ + [ad_review_center_ad_service.BatchBlockAdReviewCenterAdsRequest], + operations_pb2.Operation, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchBlockAdReviewCenterAds(self._session, self._host, self._interceptor) # type: ignore + + @property + def search_ad_review_center_ads( + self, + ) -> Callable[ + [ad_review_center_ad_service.SearchAdReviewCenterAdsRequest], + ad_review_center_ad_service.SearchAdReviewCenterAdsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._SearchAdReviewCenterAds(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseAdReviewCenterAdServiceRestTransport._BaseGetOperation, + AdReviewCenterAdServiceRestStub, + ): + def __hash__(self): + return hash("AdReviewCenterAdServiceRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = ( + _BaseAdReviewCenterAdServiceRestTransport._BaseGetOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = _BaseAdReviewCenterAdServiceRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseAdReviewCenterAdServiceRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.AdReviewCenterAdServiceClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.AdReviewCenterAdService", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = AdReviewCenterAdServiceRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.AdReviewCenterAdServiceAsyncClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.AdReviewCenterAdService", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("AdReviewCenterAdServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/transports/rest_base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/transports/rest_base.py new file mode 100644 index 000000000000..c7a488784fa5 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/ad_review_center_ad_service/transports/rest_base.py @@ -0,0 +1,290 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.ads.admanager_v1.types import ad_review_center_ad_service + +from .base import DEFAULT_CLIENT_INFO, AdReviewCenterAdServiceTransport + + +class _BaseAdReviewCenterAdServiceRestTransport(AdReviewCenterAdServiceTransport): + """Base REST backend transport for AdReviewCenterAdService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseBatchAllowAdReviewCenterAds: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*/webProperties/*}/adReviewCenterAds:batchAllow", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = ( + ad_review_center_ad_service.BatchAllowAdReviewCenterAdsRequest.pb( + request + ) + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAdReviewCenterAdServiceRestTransport._BaseBatchAllowAdReviewCenterAds._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseBatchBlockAdReviewCenterAds: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*/webProperties/*}/adReviewCenterAds:batchBlock", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = ( + ad_review_center_ad_service.BatchBlockAdReviewCenterAdsRequest.pb( + request + ) + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAdReviewCenterAdServiceRestTransport._BaseBatchBlockAdReviewCenterAds._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseSearchAdReviewCenterAds: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "status": {}, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=networks/*/webProperties/*}/adReviewCenterAds:search", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = ad_review_center_ad_service.SearchAdReviewCenterAdsRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAdReviewCenterAdServiceRestTransport._BaseSearchAdReviewCenterAds._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/operations/reports/runs/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseAdReviewCenterAdServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/__init__.py new file mode 100644 index 000000000000..2703e15b52b7 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ApplicationServiceClient + +__all__ = ("ApplicationServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/client.py new file mode 100644 index 000000000000..6f26091e1b95 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/client.py @@ -0,0 +1,1043 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +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.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version + +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.longrunning import operations_pb2 # type: ignore + +from google.ads.admanager_v1.services.application_service import pagers +from google.ads.admanager_v1.types import application_messages, application_service + +from .transports.base import DEFAULT_CLIENT_INFO, ApplicationServiceTransport +from .transports.rest import ApplicationServiceRestTransport + + +class ApplicationServiceClientMeta(type): + """Metaclass for the ApplicationService 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[ApplicationServiceTransport]] + _transport_registry["rest"] = ApplicationServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ApplicationServiceTransport]: + """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 ApplicationServiceClient(metaclass=ApplicationServiceClientMeta): + """Provides methods for handling ``Application`` objects.""" + + @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 = "admanager.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "admanager.{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: + ApplicationServiceClient: 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: + ApplicationServiceClient: 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) -> ApplicationServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ApplicationServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def application_path( + network_code: str, + application: str, + ) -> str: + """Returns a fully-qualified application string.""" + return "networks/{network_code}/applications/{application}".format( + network_code=network_code, + application=application, + ) + + @staticmethod + def parse_application_path(path: str) -> Dict[str, str]: + """Parses a application path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/applications/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def network_path( + network_code: str, + ) -> str: + """Returns a fully-qualified network string.""" + return "networks/{network_code}".format( + network_code=network_code, + ) + + @staticmethod + def parse_network_path(path: str) -> Dict[str, str]: + """Parses a network path into its component segments.""" + m = re.match(r"^networks/(?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 = ApplicationServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ApplicationServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ApplicationServiceClient._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 = ApplicationServiceClient._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, + ApplicationServiceTransport, + Callable[..., ApplicationServiceTransport], + ] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the application 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,ApplicationServiceTransport,Callable[..., ApplicationServiceTransport]]]): + 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 ApplicationServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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, + ) = ApplicationServiceClient._read_environment_variables() + self._client_cert_source = ApplicationServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = ApplicationServiceClient._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, ApplicationServiceTransport) + if transport_provided: + # transport is a ApplicationServiceTransport 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(ApplicationServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or ApplicationServiceClient._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[ApplicationServiceTransport], + Callable[..., ApplicationServiceTransport], + ] = ( + ApplicationServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., ApplicationServiceTransport], 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.admanager_v1.ApplicationServiceClient`.", + extra={ + "serviceName": "google.ads.admanager.v1.ApplicationService", + "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.admanager.v1.ApplicationService", + "credentialsType": None, + }, + ) + + def get_application( + self, + request: Optional[ + Union[application_service.GetApplicationRequest, dict] + ] = None, + *, + 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]]] = (), + ) -> application_messages.Application: + r"""API to retrieve a ``Application`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_get_application(): + # Create a client + client = admanager_v1.ApplicationServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetApplicationRequest( + name="name_value", + ) + + # Make the request + response = client.get_application(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.GetApplicationRequest, dict]): + The request object. Request object for ``GetApplication`` method. + name (str): + Required. The resource name of the Application. Format: + ``networks/{network_code}/applications/{application_id}`` + + This corresponds to the ``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.admanager_v1.types.Application: + An application that has been added to + or "claimed" by the network to be used + for targeting purposes. These mobile + apps can come from various app stores. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, application_service.GetApplicationRequest): + request = application_service.GetApplicationRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_application] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_applications( + self, + request: Optional[ + Union[application_service.ListApplicationsRequest, dict] + ] = None, + *, + parent: 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.ListApplicationsPager: + r"""API to retrieve a list of ``Application`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_list_applications(): + # Create a client + client = admanager_v1.ApplicationServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListApplicationsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_applications(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.ListApplicationsRequest, dict]): + The request object. Request object for ``ListApplications`` method. + parent (str): + Required. The parent, which owns this collection of + Applications. Format: ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.services.application_service.pagers.ListApplicationsPager: + Response object for ListApplicationsRequest containing matching + Application objects. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, application_service.ListApplicationsRequest): + request = application_service.ListApplicationsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_applications] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.ListApplicationsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ApplicationServiceClient": + 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() + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("ApplicationServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/pagers.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/pagers.py new file mode 100644 index 000000000000..7b6fd3d8cb5b --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/pagers.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +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 + +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.admanager_v1.types import application_messages, application_service + + +class ListApplicationsPager: + """A pager for iterating through ``list_applications`` requests. + + This class thinly wraps an initial + :class:`google.ads.admanager_v1.types.ListApplicationsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``applications`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListApplications`` requests and continue to iterate + through the ``applications`` field on the + corresponding responses. + + All the usual :class:`google.ads.admanager_v1.types.ListApplicationsResponse` + 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[..., application_service.ListApplicationsResponse], + request: application_service.ListApplicationsRequest, + response: application_service.ListApplicationsResponse, + *, + 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.admanager_v1.types.ListApplicationsRequest): + The initial request object. + response (google.ads.admanager_v1.types.ListApplicationsResponse): + 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 = application_service.ListApplicationsRequest(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[application_service.ListApplicationsResponse]: + 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[application_messages.Application]: + for page in self.pages: + yield from page.applications + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/transports/README.rst b/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/transports/README.rst new file mode 100644 index 000000000000..42bc947a9f22 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`ApplicationServiceTransport` is the ABC for all transports. +- public child `ApplicationServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `ApplicationServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseApplicationServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `ApplicationServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/transports/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/transports/__init__.py new file mode 100644 index 000000000000..96088f830d7c --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/transports/__init__.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 typing import Dict, Type + +from .base import ApplicationServiceTransport +from .rest import ApplicationServiceRestInterceptor, ApplicationServiceRestTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[ApplicationServiceTransport]] +_transport_registry["rest"] = ApplicationServiceRestTransport + +__all__ = ( + "ApplicationServiceTransport", + "ApplicationServiceRestTransport", + "ApplicationServiceRestInterceptor", +) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/transports/base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/transports/base.py new file mode 100644 index 000000000000..396e9d28ac69 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/transports/base.py @@ -0,0 +1,201 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version +from google.ads.admanager_v1.types import application_messages, application_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 ApplicationServiceTransport(abc.ABC): + """Abstract transport class for ApplicationService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/admanager",) + + DEFAULT_HOST: str = "admanager.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: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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_application: gapic_v1.method.wrap_method( + self.get_application, + default_timeout=None, + client_info=client_info, + ), + self.list_applications: gapic_v1.method.wrap_method( + self.list_applications, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + 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_application( + self, + ) -> Callable[ + [application_service.GetApplicationRequest], + Union[ + application_messages.Application, + Awaitable[application_messages.Application], + ], + ]: + raise NotImplementedError() + + @property + def list_applications( + self, + ) -> Callable[ + [application_service.ListApplicationsRequest], + Union[ + application_service.ListApplicationsResponse, + Awaitable[application_service.ListApplicationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ApplicationServiceTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/transports/rest.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/transports/rest.py new file mode 100644 index 000000000000..61b9c5d62503 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/transports/rest.py @@ -0,0 +1,786 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.ads.admanager_v1.types import application_messages, application_service + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseApplicationServiceRestTransport + +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 = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class ApplicationServiceRestInterceptor: + """Interceptor for ApplicationService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the ApplicationServiceRestTransport. + + .. code-block:: python + class MyCustomApplicationServiceInterceptor(ApplicationServiceRestInterceptor): + def pre_get_application(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_application(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_applications(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_applications(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ApplicationServiceRestTransport(interceptor=MyCustomApplicationServiceInterceptor()) + client = ApplicationServiceClient(transport=transport) + + + """ + + def pre_get_application( + self, + request: application_service.GetApplicationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + application_service.GetApplicationRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for get_application + + Override in a subclass to manipulate the request or metadata + before they are sent to the ApplicationService server. + """ + return request, metadata + + def post_get_application( + self, response: application_messages.Application + ) -> application_messages.Application: + """Post-rpc interceptor for get_application + + DEPRECATED. Please use the `post_get_application_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the ApplicationService server but before + it is returned to user code. This `post_get_application` interceptor runs + before the `post_get_application_with_metadata` interceptor. + """ + return response + + def post_get_application_with_metadata( + self, + response: application_messages.Application, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + application_messages.Application, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_application + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ApplicationService server but before it is returned to user code. + + We recommend only using this `post_get_application_with_metadata` + interceptor in new development instead of the `post_get_application` interceptor. + When both interceptors are used, this `post_get_application_with_metadata` interceptor runs after the + `post_get_application` interceptor. The (possibly modified) response returned by + `post_get_application` will be passed to + `post_get_application_with_metadata`. + """ + return response, metadata + + def pre_list_applications( + self, + request: application_service.ListApplicationsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + application_service.ListApplicationsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for list_applications + + Override in a subclass to manipulate the request or metadata + before they are sent to the ApplicationService server. + """ + return request, metadata + + def post_list_applications( + self, response: application_service.ListApplicationsResponse + ) -> application_service.ListApplicationsResponse: + """Post-rpc interceptor for list_applications + + DEPRECATED. Please use the `post_list_applications_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the ApplicationService server but before + it is returned to user code. This `post_list_applications` interceptor runs + before the `post_list_applications_with_metadata` interceptor. + """ + return response + + def post_list_applications_with_metadata( + self, + response: application_service.ListApplicationsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + application_service.ListApplicationsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_applications + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ApplicationService server but before it is returned to user code. + + We recommend only using this `post_list_applications_with_metadata` + interceptor in new development instead of the `post_list_applications` interceptor. + When both interceptors are used, this `post_list_applications_with_metadata` interceptor runs after the + `post_list_applications` interceptor. The (possibly modified) response returned by + `post_list_applications` will be passed to + `post_list_applications_with_metadata`. + """ + return response, metadata + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the ApplicationService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the ApplicationService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ApplicationServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ApplicationServiceRestInterceptor + + +class ApplicationServiceRestTransport(_BaseApplicationServiceRestTransport): + """REST backend synchronous transport for ApplicationService. + + Provides methods for handling ``Application`` objects. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[ApplicationServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or ApplicationServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _GetApplication( + _BaseApplicationServiceRestTransport._BaseGetApplication, + ApplicationServiceRestStub, + ): + def __hash__(self): + return hash("ApplicationServiceRestTransport.GetApplication") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: application_service.GetApplicationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> application_messages.Application: + r"""Call the get application method over HTTP. + + Args: + request (~.application_service.GetApplicationRequest): + The request object. Request object for ``GetApplication`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.application_messages.Application: + An application that has been added to + or "claimed" by the network to be used + for targeting purposes. These mobile + apps can come from various app stores. + + """ + + http_options = ( + _BaseApplicationServiceRestTransport._BaseGetApplication._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_application(request, metadata) + transcoded_request = _BaseApplicationServiceRestTransport._BaseGetApplication._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseApplicationServiceRestTransport._BaseGetApplication._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.ApplicationServiceClient.GetApplication", + extra={ + "serviceName": "google.ads.admanager.v1.ApplicationService", + "rpcName": "GetApplication", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ApplicationServiceRestTransport._GetApplication._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = application_messages.Application() + pb_resp = application_messages.Application.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_application(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_application_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = application_messages.Application.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.ApplicationServiceClient.get_application", + extra={ + "serviceName": "google.ads.admanager.v1.ApplicationService", + "rpcName": "GetApplication", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListApplications( + _BaseApplicationServiceRestTransport._BaseListApplications, + ApplicationServiceRestStub, + ): + def __hash__(self): + return hash("ApplicationServiceRestTransport.ListApplications") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: application_service.ListApplicationsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> application_service.ListApplicationsResponse: + r"""Call the list applications method over HTTP. + + Args: + request (~.application_service.ListApplicationsRequest): + The request object. Request object for ``ListApplications`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.application_service.ListApplicationsResponse: + Response object for ``ListApplicationsRequest`` + containing matching ``Application`` objects. + + """ + + http_options = ( + _BaseApplicationServiceRestTransport._BaseListApplications._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_applications( + request, metadata + ) + transcoded_request = _BaseApplicationServiceRestTransport._BaseListApplications._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseApplicationServiceRestTransport._BaseListApplications._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.ApplicationServiceClient.ListApplications", + extra={ + "serviceName": "google.ads.admanager.v1.ApplicationService", + "rpcName": "ListApplications", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ApplicationServiceRestTransport._ListApplications._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = application_service.ListApplicationsResponse() + pb_resp = application_service.ListApplicationsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_applications(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_applications_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + application_service.ListApplicationsResponse.to_json(response) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.ApplicationServiceClient.list_applications", + extra={ + "serviceName": "google.ads.admanager.v1.ApplicationService", + "rpcName": "ListApplications", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def get_application( + self, + ) -> Callable[ + [application_service.GetApplicationRequest], application_messages.Application + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetApplication(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_applications( + self, + ) -> Callable[ + [application_service.ListApplicationsRequest], + application_service.ListApplicationsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListApplications(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseApplicationServiceRestTransport._BaseGetOperation, + ApplicationServiceRestStub, + ): + def __hash__(self): + return hash("ApplicationServiceRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = ( + _BaseApplicationServiceRestTransport._BaseGetOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = _BaseApplicationServiceRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseApplicationServiceRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.ApplicationServiceClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.ApplicationService", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ApplicationServiceRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.ApplicationServiceAsyncClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.ApplicationService", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("ApplicationServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/transports/rest_base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/transports/rest_base.py new file mode 100644 index 000000000000..373dbb4ac79a --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/application_service/transports/rest_base.py @@ -0,0 +1,211 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.ads.admanager_v1.types import application_messages, application_service + +from .base import DEFAULT_CLIENT_INFO, ApplicationServiceTransport + + +class _BaseApplicationServiceRestTransport(ApplicationServiceTransport): + """Base REST backend transport for ApplicationService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetApplication: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/applications/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = application_service.GetApplicationRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseApplicationServiceRestTransport._BaseGetApplication._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListApplications: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=networks/*}/applications", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = application_service.ListApplicationsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseApplicationServiceRestTransport._BaseListApplications._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/operations/reports/runs/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseApplicationServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/__init__.py new file mode 100644 index 000000000000..a97c850c69d2 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 AudienceSegmentServiceClient + +__all__ = ("AudienceSegmentServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/client.py new file mode 100644 index 000000000000..4c2ab6621e80 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/client.py @@ -0,0 +1,1049 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +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.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version + +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.longrunning import operations_pb2 # type: ignore + +from google.ads.admanager_v1.services.audience_segment_service import pagers +from google.ads.admanager_v1.types import ( + audience_segment_messages, + audience_segment_service, +) + +from .transports.base import DEFAULT_CLIENT_INFO, AudienceSegmentServiceTransport +from .transports.rest import AudienceSegmentServiceRestTransport + + +class AudienceSegmentServiceClientMeta(type): + """Metaclass for the AudienceSegmentService 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[AudienceSegmentServiceTransport]] + _transport_registry["rest"] = AudienceSegmentServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AudienceSegmentServiceTransport]: + """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 AudienceSegmentServiceClient(metaclass=AudienceSegmentServiceClientMeta): + """Provides methods for handling ``AudienceSegment`` objects.""" + + @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 = "admanager.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "admanager.{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: + AudienceSegmentServiceClient: 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: + AudienceSegmentServiceClient: 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) -> AudienceSegmentServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AudienceSegmentServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def audience_segment_path( + network_code: str, + audience_segment: str, + ) -> str: + """Returns a fully-qualified audience_segment string.""" + return "networks/{network_code}/audienceSegments/{audience_segment}".format( + network_code=network_code, + audience_segment=audience_segment, + ) + + @staticmethod + def parse_audience_segment_path(path: str) -> Dict[str, str]: + """Parses a audience_segment path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/audienceSegments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def network_path( + network_code: str, + ) -> str: + """Returns a fully-qualified network string.""" + return "networks/{network_code}".format( + network_code=network_code, + ) + + @staticmethod + def parse_network_path(path: str) -> Dict[str, str]: + """Parses a network path into its component segments.""" + m = re.match(r"^networks/(?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 = AudienceSegmentServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AudienceSegmentServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + AudienceSegmentServiceClient._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 = AudienceSegmentServiceClient._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, + AudienceSegmentServiceTransport, + Callable[..., AudienceSegmentServiceTransport], + ] + ] = 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 segment 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,AudienceSegmentServiceTransport,Callable[..., AudienceSegmentServiceTransport]]]): + 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 AudienceSegmentServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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, + ) = AudienceSegmentServiceClient._read_environment_variables() + self._client_cert_source = AudienceSegmentServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = AudienceSegmentServiceClient._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, AudienceSegmentServiceTransport) + if transport_provided: + # transport is a AudienceSegmentServiceTransport 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(AudienceSegmentServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AudienceSegmentServiceClient._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[AudienceSegmentServiceTransport], + Callable[..., AudienceSegmentServiceTransport], + ] = ( + AudienceSegmentServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., AudienceSegmentServiceTransport], 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.admanager_v1.AudienceSegmentServiceClient`.", + extra={ + "serviceName": "google.ads.admanager.v1.AudienceSegmentService", + "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.admanager.v1.AudienceSegmentService", + "credentialsType": None, + }, + ) + + def get_audience_segment( + self, + request: Optional[ + Union[audience_segment_service.GetAudienceSegmentRequest, dict] + ] = None, + *, + 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]]] = (), + ) -> audience_segment_messages.AudienceSegment: + r"""API to retrieve an ``AudienceSegment`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_get_audience_segment(): + # Create a client + client = admanager_v1.AudienceSegmentServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetAudienceSegmentRequest( + name="name_value", + ) + + # Make the request + response = client.get_audience_segment(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.GetAudienceSegmentRequest, dict]): + The request object. Request object for ``GetAudienceSegment`` method. + name (str): + Required. The resource name of the AudienceSegment. + Format: + ``networks/{network_code}/audienceSegments/{audience_segment_id}`` + + This corresponds to the ``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.admanager_v1.types.AudienceSegment: + The AudienceSegment resource. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, audience_segment_service.GetAudienceSegmentRequest): + request = audience_segment_service.GetAudienceSegmentRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_audience_segment] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_audience_segments( + self, + request: Optional[ + Union[audience_segment_service.ListAudienceSegmentsRequest, dict] + ] = None, + *, + parent: 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.ListAudienceSegmentsPager: + r"""API to retrieve a list of ``AudienceSegment`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_list_audience_segments(): + # Create a client + client = admanager_v1.AudienceSegmentServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListAudienceSegmentsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_audience_segments(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.ListAudienceSegmentsRequest, dict]): + The request object. Request object for ``ListAudienceSegments`` method. + parent (str): + Required. The parent publisher network associated with + these audience segments. Format: + ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.services.audience_segment_service.pagers.ListAudienceSegmentsPager: + Response object for ListAudienceSegmentsRequest containing matching + AudienceSegment objects. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request 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_segment_service.ListAudienceSegmentsRequest + ): + request = audience_segment_service.ListAudienceSegmentsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_audience_segments] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.ListAudienceSegmentsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AudienceSegmentServiceClient": + 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() + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AudienceSegmentServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/pagers.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/pagers.py new file mode 100644 index 000000000000..8940bd966b66 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/pagers.py @@ -0,0 +1,120 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +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 + +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.admanager_v1.types import ( + audience_segment_messages, + audience_segment_service, +) + + +class ListAudienceSegmentsPager: + """A pager for iterating through ``list_audience_segments`` requests. + + This class thinly wraps an initial + :class:`google.ads.admanager_v1.types.ListAudienceSegmentsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``audience_segments`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListAudienceSegments`` requests and continue to iterate + through the ``audience_segments`` field on the + corresponding responses. + + All the usual :class:`google.ads.admanager_v1.types.ListAudienceSegmentsResponse` + 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[..., audience_segment_service.ListAudienceSegmentsResponse], + request: audience_segment_service.ListAudienceSegmentsRequest, + response: audience_segment_service.ListAudienceSegmentsResponse, + *, + 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.admanager_v1.types.ListAudienceSegmentsRequest): + The initial request object. + response (google.ads.admanager_v1.types.ListAudienceSegmentsResponse): + 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 = audience_segment_service.ListAudienceSegmentsRequest(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[audience_segment_service.ListAudienceSegmentsResponse]: + 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[audience_segment_messages.AudienceSegment]: + for page in self.pages: + yield from page.audience_segments + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/transports/README.rst b/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/transports/README.rst new file mode 100644 index 000000000000..fe685a189df3 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`AudienceSegmentServiceTransport` is the ABC for all transports. +- public child `AudienceSegmentServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `AudienceSegmentServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseAudienceSegmentServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `AudienceSegmentServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/transports/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/transports/__init__.py new file mode 100644 index 000000000000..caf4d2aa56d1 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/transports/__init__.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 typing import Dict, Type + +from .base import AudienceSegmentServiceTransport +from .rest import ( + AudienceSegmentServiceRestInterceptor, + AudienceSegmentServiceRestTransport, +) + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AudienceSegmentServiceTransport]] +_transport_registry["rest"] = AudienceSegmentServiceRestTransport + +__all__ = ( + "AudienceSegmentServiceTransport", + "AudienceSegmentServiceRestTransport", + "AudienceSegmentServiceRestInterceptor", +) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/transports/base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/transports/base.py new file mode 100644 index 000000000000..38b6f8ea3840 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/transports/base.py @@ -0,0 +1,204 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version +from google.ads.admanager_v1.types import ( + audience_segment_messages, + audience_segment_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 AudienceSegmentServiceTransport(abc.ABC): + """Abstract transport class for AudienceSegmentService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/admanager",) + + DEFAULT_HOST: str = "admanager.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: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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_audience_segment: gapic_v1.method.wrap_method( + self.get_audience_segment, + default_timeout=None, + client_info=client_info, + ), + self.list_audience_segments: gapic_v1.method.wrap_method( + self.list_audience_segments, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + 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_audience_segment( + self, + ) -> Callable[ + [audience_segment_service.GetAudienceSegmentRequest], + Union[ + audience_segment_messages.AudienceSegment, + Awaitable[audience_segment_messages.AudienceSegment], + ], + ]: + raise NotImplementedError() + + @property + def list_audience_segments( + self, + ) -> Callable[ + [audience_segment_service.ListAudienceSegmentsRequest], + Union[ + audience_segment_service.ListAudienceSegmentsResponse, + Awaitable[audience_segment_service.ListAudienceSegmentsResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AudienceSegmentServiceTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/transports/rest.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/transports/rest.py new file mode 100644 index 000000000000..f41c5533858a --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/transports/rest.py @@ -0,0 +1,795 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.ads.admanager_v1.types import ( + audience_segment_messages, + audience_segment_service, +) + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseAudienceSegmentServiceRestTransport + +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 = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AudienceSegmentServiceRestInterceptor: + """Interceptor for AudienceSegmentService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the AudienceSegmentServiceRestTransport. + + .. code-block:: python + class MyCustomAudienceSegmentServiceInterceptor(AudienceSegmentServiceRestInterceptor): + def pre_get_audience_segment(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_audience_segment(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_audience_segments(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_audience_segments(self, response): + logging.log(f"Received response: {response}") + return response + + transport = AudienceSegmentServiceRestTransport(interceptor=MyCustomAudienceSegmentServiceInterceptor()) + client = AudienceSegmentServiceClient(transport=transport) + + + """ + + def pre_get_audience_segment( + self, + request: audience_segment_service.GetAudienceSegmentRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + audience_segment_service.GetAudienceSegmentRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for get_audience_segment + + Override in a subclass to manipulate the request or metadata + before they are sent to the AudienceSegmentService server. + """ + return request, metadata + + def post_get_audience_segment( + self, response: audience_segment_messages.AudienceSegment + ) -> audience_segment_messages.AudienceSegment: + """Post-rpc interceptor for get_audience_segment + + DEPRECATED. Please use the `post_get_audience_segment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the AudienceSegmentService server but before + it is returned to user code. This `post_get_audience_segment` interceptor runs + before the `post_get_audience_segment_with_metadata` interceptor. + """ + return response + + def post_get_audience_segment_with_metadata( + self, + response: audience_segment_messages.AudienceSegment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + audience_segment_messages.AudienceSegment, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for get_audience_segment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the AudienceSegmentService server but before it is returned to user code. + + We recommend only using this `post_get_audience_segment_with_metadata` + interceptor in new development instead of the `post_get_audience_segment` interceptor. + When both interceptors are used, this `post_get_audience_segment_with_metadata` interceptor runs after the + `post_get_audience_segment` interceptor. The (possibly modified) response returned by + `post_get_audience_segment` will be passed to + `post_get_audience_segment_with_metadata`. + """ + return response, metadata + + def pre_list_audience_segments( + self, + request: audience_segment_service.ListAudienceSegmentsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + audience_segment_service.ListAudienceSegmentsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for list_audience_segments + + Override in a subclass to manipulate the request or metadata + before they are sent to the AudienceSegmentService server. + """ + return request, metadata + + def post_list_audience_segments( + self, response: audience_segment_service.ListAudienceSegmentsResponse + ) -> audience_segment_service.ListAudienceSegmentsResponse: + """Post-rpc interceptor for list_audience_segments + + DEPRECATED. Please use the `post_list_audience_segments_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the AudienceSegmentService server but before + it is returned to user code. This `post_list_audience_segments` interceptor runs + before the `post_list_audience_segments_with_metadata` interceptor. + """ + return response + + def post_list_audience_segments_with_metadata( + self, + response: audience_segment_service.ListAudienceSegmentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + audience_segment_service.ListAudienceSegmentsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_audience_segments + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the AudienceSegmentService server but before it is returned to user code. + + We recommend only using this `post_list_audience_segments_with_metadata` + interceptor in new development instead of the `post_list_audience_segments` interceptor. + When both interceptors are used, this `post_list_audience_segments_with_metadata` interceptor runs after the + `post_list_audience_segments` interceptor. The (possibly modified) response returned by + `post_list_audience_segments` will be passed to + `post_list_audience_segments_with_metadata`. + """ + return response, metadata + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the AudienceSegmentService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the AudienceSegmentService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class AudienceSegmentServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: AudienceSegmentServiceRestInterceptor + + +class AudienceSegmentServiceRestTransport(_BaseAudienceSegmentServiceRestTransport): + """REST backend synchronous transport for AudienceSegmentService. + + Provides methods for handling ``AudienceSegment`` objects. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[AudienceSegmentServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or AudienceSegmentServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _GetAudienceSegment( + _BaseAudienceSegmentServiceRestTransport._BaseGetAudienceSegment, + AudienceSegmentServiceRestStub, + ): + def __hash__(self): + return hash("AudienceSegmentServiceRestTransport.GetAudienceSegment") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: audience_segment_service.GetAudienceSegmentRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audience_segment_messages.AudienceSegment: + r"""Call the get audience segment method over HTTP. + + Args: + request (~.audience_segment_service.GetAudienceSegmentRequest): + The request object. Request object for ``GetAudienceSegment`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.audience_segment_messages.AudienceSegment: + The ``AudienceSegment`` resource. + """ + + http_options = ( + _BaseAudienceSegmentServiceRestTransport._BaseGetAudienceSegment._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_audience_segment( + request, metadata + ) + transcoded_request = _BaseAudienceSegmentServiceRestTransport._BaseGetAudienceSegment._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseAudienceSegmentServiceRestTransport._BaseGetAudienceSegment._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.AudienceSegmentServiceClient.GetAudienceSegment", + extra={ + "serviceName": "google.ads.admanager.v1.AudienceSegmentService", + "rpcName": "GetAudienceSegment", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + AudienceSegmentServiceRestTransport._GetAudienceSegment._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = audience_segment_messages.AudienceSegment() + pb_resp = audience_segment_messages.AudienceSegment.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_audience_segment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_audience_segment_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + audience_segment_messages.AudienceSegment.to_json(response) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.AudienceSegmentServiceClient.get_audience_segment", + extra={ + "serviceName": "google.ads.admanager.v1.AudienceSegmentService", + "rpcName": "GetAudienceSegment", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListAudienceSegments( + _BaseAudienceSegmentServiceRestTransport._BaseListAudienceSegments, + AudienceSegmentServiceRestStub, + ): + def __hash__(self): + return hash("AudienceSegmentServiceRestTransport.ListAudienceSegments") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: audience_segment_service.ListAudienceSegmentsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audience_segment_service.ListAudienceSegmentsResponse: + r"""Call the list audience segments method over HTTP. + + Args: + request (~.audience_segment_service.ListAudienceSegmentsRequest): + The request object. Request object for ``ListAudienceSegments`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.audience_segment_service.ListAudienceSegmentsResponse: + Response object for ``ListAudienceSegmentsRequest`` + containing matching ``AudienceSegment`` objects. + + """ + + http_options = ( + _BaseAudienceSegmentServiceRestTransport._BaseListAudienceSegments._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_audience_segments( + request, metadata + ) + transcoded_request = _BaseAudienceSegmentServiceRestTransport._BaseListAudienceSegments._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseAudienceSegmentServiceRestTransport._BaseListAudienceSegments._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.AudienceSegmentServiceClient.ListAudienceSegments", + extra={ + "serviceName": "google.ads.admanager.v1.AudienceSegmentService", + "rpcName": "ListAudienceSegments", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + AudienceSegmentServiceRestTransport._ListAudienceSegments._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = audience_segment_service.ListAudienceSegmentsResponse() + pb_resp = audience_segment_service.ListAudienceSegmentsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_audience_segments(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_audience_segments_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + audience_segment_service.ListAudienceSegmentsResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.AudienceSegmentServiceClient.list_audience_segments", + extra={ + "serviceName": "google.ads.admanager.v1.AudienceSegmentService", + "rpcName": "ListAudienceSegments", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def get_audience_segment( + self, + ) -> Callable[ + [audience_segment_service.GetAudienceSegmentRequest], + audience_segment_messages.AudienceSegment, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetAudienceSegment(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_audience_segments( + self, + ) -> Callable[ + [audience_segment_service.ListAudienceSegmentsRequest], + audience_segment_service.ListAudienceSegmentsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListAudienceSegments(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseAudienceSegmentServiceRestTransport._BaseGetOperation, + AudienceSegmentServiceRestStub, + ): + def __hash__(self): + return hash("AudienceSegmentServiceRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = ( + _BaseAudienceSegmentServiceRestTransport._BaseGetOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = _BaseAudienceSegmentServiceRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseAudienceSegmentServiceRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.AudienceSegmentServiceClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.AudienceSegmentService", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = AudienceSegmentServiceRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.AudienceSegmentServiceAsyncClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.AudienceSegmentService", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("AudienceSegmentServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/transports/rest_base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/transports/rest_base.py new file mode 100644 index 000000000000..d1f6be10a31d --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/audience_segment_service/transports/rest_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 json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.ads.admanager_v1.types import ( + audience_segment_messages, + audience_segment_service, +) + +from .base import DEFAULT_CLIENT_INFO, AudienceSegmentServiceTransport + + +class _BaseAudienceSegmentServiceRestTransport(AudienceSegmentServiceTransport): + """Base REST backend transport for AudienceSegmentService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetAudienceSegment: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/audienceSegments/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = audience_segment_service.GetAudienceSegmentRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAudienceSegmentServiceRestTransport._BaseGetAudienceSegment._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListAudienceSegments: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=networks/*}/audienceSegments", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = audience_segment_service.ListAudienceSegmentsRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseAudienceSegmentServiceRestTransport._BaseListAudienceSegments._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/operations/reports/runs/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseAudienceSegmentServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/__init__.py new file mode 100644 index 000000000000..45649e3db3e6 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 BrowserLanguageServiceClient + +__all__ = ("BrowserLanguageServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/client.py new file mode 100644 index 000000000000..7e2915967b7c --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/client.py @@ -0,0 +1,1048 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +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.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version + +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.longrunning import operations_pb2 # type: ignore + +from google.ads.admanager_v1.services.browser_language_service import pagers +from google.ads.admanager_v1.types import ( + browser_language_messages, + browser_language_service, +) + +from .transports.base import DEFAULT_CLIENT_INFO, BrowserLanguageServiceTransport +from .transports.rest import BrowserLanguageServiceRestTransport + + +class BrowserLanguageServiceClientMeta(type): + """Metaclass for the BrowserLanguageService 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[BrowserLanguageServiceTransport]] + _transport_registry["rest"] = BrowserLanguageServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[BrowserLanguageServiceTransport]: + """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 BrowserLanguageServiceClient(metaclass=BrowserLanguageServiceClientMeta): + """Provides methods for handling ``BrowserLanguage`` objects.""" + + @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 = "admanager.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "admanager.{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: + BrowserLanguageServiceClient: 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: + BrowserLanguageServiceClient: 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) -> BrowserLanguageServiceTransport: + """Returns the transport used by the client instance. + + Returns: + BrowserLanguageServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def browser_language_path( + network_code: str, + browser_language: str, + ) -> str: + """Returns a fully-qualified browser_language string.""" + return "networks/{network_code}/browserLanguages/{browser_language}".format( + network_code=network_code, + browser_language=browser_language, + ) + + @staticmethod + def parse_browser_language_path(path: str) -> Dict[str, str]: + """Parses a browser_language path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/browserLanguages/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def network_path( + network_code: str, + ) -> str: + """Returns a fully-qualified network string.""" + return "networks/{network_code}".format( + network_code=network_code, + ) + + @staticmethod + def parse_network_path(path: str) -> Dict[str, str]: + """Parses a network path into its component segments.""" + m = re.match(r"^networks/(?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 = BrowserLanguageServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = BrowserLanguageServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + BrowserLanguageServiceClient._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 = BrowserLanguageServiceClient._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, + BrowserLanguageServiceTransport, + Callable[..., BrowserLanguageServiceTransport], + ] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the browser language 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,BrowserLanguageServiceTransport,Callable[..., BrowserLanguageServiceTransport]]]): + 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 BrowserLanguageServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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, + ) = BrowserLanguageServiceClient._read_environment_variables() + self._client_cert_source = BrowserLanguageServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = BrowserLanguageServiceClient._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, BrowserLanguageServiceTransport) + if transport_provided: + # transport is a BrowserLanguageServiceTransport 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(BrowserLanguageServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or BrowserLanguageServiceClient._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[BrowserLanguageServiceTransport], + Callable[..., BrowserLanguageServiceTransport], + ] = ( + BrowserLanguageServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., BrowserLanguageServiceTransport], 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.admanager_v1.BrowserLanguageServiceClient`.", + extra={ + "serviceName": "google.ads.admanager.v1.BrowserLanguageService", + "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.admanager.v1.BrowserLanguageService", + "credentialsType": None, + }, + ) + + def get_browser_language( + self, + request: Optional[ + Union[browser_language_service.GetBrowserLanguageRequest, dict] + ] = None, + *, + 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]]] = (), + ) -> browser_language_messages.BrowserLanguage: + r"""API to retrieve a ``BrowserLanguage`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_get_browser_language(): + # Create a client + client = admanager_v1.BrowserLanguageServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetBrowserLanguageRequest( + name="name_value", + ) + + # Make the request + response = client.get_browser_language(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.GetBrowserLanguageRequest, dict]): + The request object. Request object for ``GetBrowserLanguage`` method. + name (str): + Required. The resource name of the BrowserLanguage. + Format: + ``networks/{network_code}/browserLanguages/{browser_language_id}`` + + This corresponds to the ``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.admanager_v1.types.BrowserLanguage: + Represents the language of a browser. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, browser_language_service.GetBrowserLanguageRequest): + request = browser_language_service.GetBrowserLanguageRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_browser_language] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_browser_languages( + self, + request: Optional[ + Union[browser_language_service.ListBrowserLanguagesRequest, dict] + ] = None, + *, + parent: 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.ListBrowserLanguagesPager: + r"""API to retrieve a list of ``BrowserLanguage`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_list_browser_languages(): + # Create a client + client = admanager_v1.BrowserLanguageServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListBrowserLanguagesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_browser_languages(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.ListBrowserLanguagesRequest, dict]): + The request object. Request object for ``ListBrowserLanguages`` method. + parent (str): + Required. The parent, which owns this collection of + BrowserLanguages. Format: ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.services.browser_language_service.pagers.ListBrowserLanguagesPager: + Response object for ListBrowserLanguagesRequest containing matching + BrowserLanguage objects. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, browser_language_service.ListBrowserLanguagesRequest + ): + request = browser_language_service.ListBrowserLanguagesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_browser_languages] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.ListBrowserLanguagesPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "BrowserLanguageServiceClient": + 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() + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("BrowserLanguageServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/pagers.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/pagers.py new file mode 100644 index 000000000000..29c5432dec77 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/pagers.py @@ -0,0 +1,120 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +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 + +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.admanager_v1.types import ( + browser_language_messages, + browser_language_service, +) + + +class ListBrowserLanguagesPager: + """A pager for iterating through ``list_browser_languages`` requests. + + This class thinly wraps an initial + :class:`google.ads.admanager_v1.types.ListBrowserLanguagesResponse` object, and + provides an ``__iter__`` method to iterate through its + ``browser_languages`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListBrowserLanguages`` requests and continue to iterate + through the ``browser_languages`` field on the + corresponding responses. + + All the usual :class:`google.ads.admanager_v1.types.ListBrowserLanguagesResponse` + 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[..., browser_language_service.ListBrowserLanguagesResponse], + request: browser_language_service.ListBrowserLanguagesRequest, + response: browser_language_service.ListBrowserLanguagesResponse, + *, + 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.admanager_v1.types.ListBrowserLanguagesRequest): + The initial request object. + response (google.ads.admanager_v1.types.ListBrowserLanguagesResponse): + 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 = browser_language_service.ListBrowserLanguagesRequest(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[browser_language_service.ListBrowserLanguagesResponse]: + 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[browser_language_messages.BrowserLanguage]: + for page in self.pages: + yield from page.browser_languages + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/transports/README.rst b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/transports/README.rst new file mode 100644 index 000000000000..0d8aa957ddb2 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`BrowserLanguageServiceTransport` is the ABC for all transports. +- public child `BrowserLanguageServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `BrowserLanguageServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseBrowserLanguageServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `BrowserLanguageServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/transports/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/transports/__init__.py new file mode 100644 index 000000000000..b3d0a4067c54 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/transports/__init__.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 typing import Dict, Type + +from .base import BrowserLanguageServiceTransport +from .rest import ( + BrowserLanguageServiceRestInterceptor, + BrowserLanguageServiceRestTransport, +) + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[BrowserLanguageServiceTransport]] +_transport_registry["rest"] = BrowserLanguageServiceRestTransport + +__all__ = ( + "BrowserLanguageServiceTransport", + "BrowserLanguageServiceRestTransport", + "BrowserLanguageServiceRestInterceptor", +) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/transports/base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/transports/base.py new file mode 100644 index 000000000000..e4618b2f703e --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/transports/base.py @@ -0,0 +1,204 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version +from google.ads.admanager_v1.types import ( + browser_language_messages, + browser_language_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 BrowserLanguageServiceTransport(abc.ABC): + """Abstract transport class for BrowserLanguageService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/admanager",) + + DEFAULT_HOST: str = "admanager.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: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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_browser_language: gapic_v1.method.wrap_method( + self.get_browser_language, + default_timeout=None, + client_info=client_info, + ), + self.list_browser_languages: gapic_v1.method.wrap_method( + self.list_browser_languages, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + 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_browser_language( + self, + ) -> Callable[ + [browser_language_service.GetBrowserLanguageRequest], + Union[ + browser_language_messages.BrowserLanguage, + Awaitable[browser_language_messages.BrowserLanguage], + ], + ]: + raise NotImplementedError() + + @property + def list_browser_languages( + self, + ) -> Callable[ + [browser_language_service.ListBrowserLanguagesRequest], + Union[ + browser_language_service.ListBrowserLanguagesResponse, + Awaitable[browser_language_service.ListBrowserLanguagesResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("BrowserLanguageServiceTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/transports/rest.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/transports/rest.py new file mode 100644 index 000000000000..a8b8fcbad57c --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/transports/rest.py @@ -0,0 +1,795 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.ads.admanager_v1.types import ( + browser_language_messages, + browser_language_service, +) + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseBrowserLanguageServiceRestTransport + +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 = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class BrowserLanguageServiceRestInterceptor: + """Interceptor for BrowserLanguageService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the BrowserLanguageServiceRestTransport. + + .. code-block:: python + class MyCustomBrowserLanguageServiceInterceptor(BrowserLanguageServiceRestInterceptor): + def pre_get_browser_language(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_browser_language(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_browser_languages(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_browser_languages(self, response): + logging.log(f"Received response: {response}") + return response + + transport = BrowserLanguageServiceRestTransport(interceptor=MyCustomBrowserLanguageServiceInterceptor()) + client = BrowserLanguageServiceClient(transport=transport) + + + """ + + def pre_get_browser_language( + self, + request: browser_language_service.GetBrowserLanguageRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + browser_language_service.GetBrowserLanguageRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for get_browser_language + + Override in a subclass to manipulate the request or metadata + before they are sent to the BrowserLanguageService server. + """ + return request, metadata + + def post_get_browser_language( + self, response: browser_language_messages.BrowserLanguage + ) -> browser_language_messages.BrowserLanguage: + """Post-rpc interceptor for get_browser_language + + DEPRECATED. Please use the `post_get_browser_language_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the BrowserLanguageService server but before + it is returned to user code. This `post_get_browser_language` interceptor runs + before the `post_get_browser_language_with_metadata` interceptor. + """ + return response + + def post_get_browser_language_with_metadata( + self, + response: browser_language_messages.BrowserLanguage, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + browser_language_messages.BrowserLanguage, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for get_browser_language + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the BrowserLanguageService server but before it is returned to user code. + + We recommend only using this `post_get_browser_language_with_metadata` + interceptor in new development instead of the `post_get_browser_language` interceptor. + When both interceptors are used, this `post_get_browser_language_with_metadata` interceptor runs after the + `post_get_browser_language` interceptor. The (possibly modified) response returned by + `post_get_browser_language` will be passed to + `post_get_browser_language_with_metadata`. + """ + return response, metadata + + def pre_list_browser_languages( + self, + request: browser_language_service.ListBrowserLanguagesRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + browser_language_service.ListBrowserLanguagesRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for list_browser_languages + + Override in a subclass to manipulate the request or metadata + before they are sent to the BrowserLanguageService server. + """ + return request, metadata + + def post_list_browser_languages( + self, response: browser_language_service.ListBrowserLanguagesResponse + ) -> browser_language_service.ListBrowserLanguagesResponse: + """Post-rpc interceptor for list_browser_languages + + DEPRECATED. Please use the `post_list_browser_languages_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the BrowserLanguageService server but before + it is returned to user code. This `post_list_browser_languages` interceptor runs + before the `post_list_browser_languages_with_metadata` interceptor. + """ + return response + + def post_list_browser_languages_with_metadata( + self, + response: browser_language_service.ListBrowserLanguagesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + browser_language_service.ListBrowserLanguagesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_browser_languages + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the BrowserLanguageService server but before it is returned to user code. + + We recommend only using this `post_list_browser_languages_with_metadata` + interceptor in new development instead of the `post_list_browser_languages` interceptor. + When both interceptors are used, this `post_list_browser_languages_with_metadata` interceptor runs after the + `post_list_browser_languages` interceptor. The (possibly modified) response returned by + `post_list_browser_languages` will be passed to + `post_list_browser_languages_with_metadata`. + """ + return response, metadata + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the BrowserLanguageService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the BrowserLanguageService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class BrowserLanguageServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: BrowserLanguageServiceRestInterceptor + + +class BrowserLanguageServiceRestTransport(_BaseBrowserLanguageServiceRestTransport): + """REST backend synchronous transport for BrowserLanguageService. + + Provides methods for handling ``BrowserLanguage`` objects. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[BrowserLanguageServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or BrowserLanguageServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _GetBrowserLanguage( + _BaseBrowserLanguageServiceRestTransport._BaseGetBrowserLanguage, + BrowserLanguageServiceRestStub, + ): + def __hash__(self): + return hash("BrowserLanguageServiceRestTransport.GetBrowserLanguage") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: browser_language_service.GetBrowserLanguageRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> browser_language_messages.BrowserLanguage: + r"""Call the get browser language method over HTTP. + + Args: + request (~.browser_language_service.GetBrowserLanguageRequest): + The request object. Request object for ``GetBrowserLanguage`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.browser_language_messages.BrowserLanguage: + Represents the language of a browser. + """ + + http_options = ( + _BaseBrowserLanguageServiceRestTransport._BaseGetBrowserLanguage._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_browser_language( + request, metadata + ) + transcoded_request = _BaseBrowserLanguageServiceRestTransport._BaseGetBrowserLanguage._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseBrowserLanguageServiceRestTransport._BaseGetBrowserLanguage._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.BrowserLanguageServiceClient.GetBrowserLanguage", + extra={ + "serviceName": "google.ads.admanager.v1.BrowserLanguageService", + "rpcName": "GetBrowserLanguage", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + BrowserLanguageServiceRestTransport._GetBrowserLanguage._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = browser_language_messages.BrowserLanguage() + pb_resp = browser_language_messages.BrowserLanguage.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_browser_language(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_browser_language_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + browser_language_messages.BrowserLanguage.to_json(response) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.BrowserLanguageServiceClient.get_browser_language", + extra={ + "serviceName": "google.ads.admanager.v1.BrowserLanguageService", + "rpcName": "GetBrowserLanguage", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListBrowserLanguages( + _BaseBrowserLanguageServiceRestTransport._BaseListBrowserLanguages, + BrowserLanguageServiceRestStub, + ): + def __hash__(self): + return hash("BrowserLanguageServiceRestTransport.ListBrowserLanguages") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: browser_language_service.ListBrowserLanguagesRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> browser_language_service.ListBrowserLanguagesResponse: + r"""Call the list browser languages method over HTTP. + + Args: + request (~.browser_language_service.ListBrowserLanguagesRequest): + The request object. Request object for ``ListBrowserLanguages`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.browser_language_service.ListBrowserLanguagesResponse: + Response object for ``ListBrowserLanguagesRequest`` + containing matching ``BrowserLanguage`` objects. + + """ + + http_options = ( + _BaseBrowserLanguageServiceRestTransport._BaseListBrowserLanguages._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_browser_languages( + request, metadata + ) + transcoded_request = _BaseBrowserLanguageServiceRestTransport._BaseListBrowserLanguages._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseBrowserLanguageServiceRestTransport._BaseListBrowserLanguages._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.BrowserLanguageServiceClient.ListBrowserLanguages", + extra={ + "serviceName": "google.ads.admanager.v1.BrowserLanguageService", + "rpcName": "ListBrowserLanguages", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + BrowserLanguageServiceRestTransport._ListBrowserLanguages._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = browser_language_service.ListBrowserLanguagesResponse() + pb_resp = browser_language_service.ListBrowserLanguagesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_browser_languages(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_browser_languages_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + browser_language_service.ListBrowserLanguagesResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.BrowserLanguageServiceClient.list_browser_languages", + extra={ + "serviceName": "google.ads.admanager.v1.BrowserLanguageService", + "rpcName": "ListBrowserLanguages", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def get_browser_language( + self, + ) -> Callable[ + [browser_language_service.GetBrowserLanguageRequest], + browser_language_messages.BrowserLanguage, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetBrowserLanguage(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_browser_languages( + self, + ) -> Callable[ + [browser_language_service.ListBrowserLanguagesRequest], + browser_language_service.ListBrowserLanguagesResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListBrowserLanguages(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseBrowserLanguageServiceRestTransport._BaseGetOperation, + BrowserLanguageServiceRestStub, + ): + def __hash__(self): + return hash("BrowserLanguageServiceRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = ( + _BaseBrowserLanguageServiceRestTransport._BaseGetOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = _BaseBrowserLanguageServiceRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseBrowserLanguageServiceRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.BrowserLanguageServiceClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.BrowserLanguageService", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = BrowserLanguageServiceRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.BrowserLanguageServiceAsyncClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.BrowserLanguageService", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("BrowserLanguageServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/transports/rest_base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/transports/rest_base.py new file mode 100644 index 000000000000..ef44086d0a4a --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_language_service/transports/rest_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 json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.ads.admanager_v1.types import ( + browser_language_messages, + browser_language_service, +) + +from .base import DEFAULT_CLIENT_INFO, BrowserLanguageServiceTransport + + +class _BaseBrowserLanguageServiceRestTransport(BrowserLanguageServiceTransport): + """Base REST backend transport for BrowserLanguageService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetBrowserLanguage: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/browserLanguages/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = browser_language_service.GetBrowserLanguageRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseBrowserLanguageServiceRestTransport._BaseGetBrowserLanguage._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListBrowserLanguages: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=networks/*}/browserLanguages", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = browser_language_service.ListBrowserLanguagesRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseBrowserLanguageServiceRestTransport._BaseListBrowserLanguages._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/operations/reports/runs/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseBrowserLanguageServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/__init__.py new file mode 100644 index 000000000000..415f1daf3524 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 BrowserServiceClient + +__all__ = ("BrowserServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/client.py new file mode 100644 index 000000000000..7282073a7cfa --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/client.py @@ -0,0 +1,1032 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +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.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version + +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.longrunning import operations_pb2 # type: ignore + +from google.ads.admanager_v1.services.browser_service import pagers +from google.ads.admanager_v1.types import browser_messages, browser_service + +from .transports.base import DEFAULT_CLIENT_INFO, BrowserServiceTransport +from .transports.rest import BrowserServiceRestTransport + + +class BrowserServiceClientMeta(type): + """Metaclass for the BrowserService 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[BrowserServiceTransport]] + _transport_registry["rest"] = BrowserServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[BrowserServiceTransport]: + """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 BrowserServiceClient(metaclass=BrowserServiceClientMeta): + """Provides methods for handling ``Browser`` objects.""" + + @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 = "admanager.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "admanager.{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: + BrowserServiceClient: 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: + BrowserServiceClient: 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) -> BrowserServiceTransport: + """Returns the transport used by the client instance. + + Returns: + BrowserServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def browser_path( + network_code: str, + browser: str, + ) -> str: + """Returns a fully-qualified browser string.""" + return "networks/{network_code}/browsers/{browser}".format( + network_code=network_code, + browser=browser, + ) + + @staticmethod + def parse_browser_path(path: str) -> Dict[str, str]: + """Parses a browser path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/browsers/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def network_path( + network_code: str, + ) -> str: + """Returns a fully-qualified network string.""" + return "networks/{network_code}".format( + network_code=network_code, + ) + + @staticmethod + def parse_network_path(path: str) -> Dict[str, str]: + """Parses a network path into its component segments.""" + m = re.match(r"^networks/(?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 = BrowserServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = BrowserServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = BrowserServiceClient._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 = BrowserServiceClient._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, BrowserServiceTransport, Callable[..., BrowserServiceTransport]] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the browser 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,BrowserServiceTransport,Callable[..., BrowserServiceTransport]]]): + 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 BrowserServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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, + ) = BrowserServiceClient._read_environment_variables() + self._client_cert_source = BrowserServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = BrowserServiceClient._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, BrowserServiceTransport) + if transport_provided: + # transport is a BrowserServiceTransport 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(BrowserServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or BrowserServiceClient._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[BrowserServiceTransport], Callable[..., BrowserServiceTransport] + ] = ( + BrowserServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., BrowserServiceTransport], 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.admanager_v1.BrowserServiceClient`.", + extra={ + "serviceName": "google.ads.admanager.v1.BrowserService", + "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.admanager.v1.BrowserService", + "credentialsType": None, + }, + ) + + def get_browser( + self, + request: Optional[Union[browser_service.GetBrowserRequest, dict]] = None, + *, + 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]]] = (), + ) -> browser_messages.Browser: + r"""API to retrieve a ``Browser`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_get_browser(): + # Create a client + client = admanager_v1.BrowserServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetBrowserRequest( + name="name_value", + ) + + # Make the request + response = client.get_browser(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.GetBrowserRequest, dict]): + The request object. Request object for ``GetBrowser`` method. + name (str): + Required. The resource name of the Browser. Format: + ``networks/{network_code}/browsers/{browser_id}`` + + This corresponds to the ``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.admanager_v1.types.Browser: + Represents a browser, including its + version. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, browser_service.GetBrowserRequest): + request = browser_service.GetBrowserRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_browser] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_browsers( + self, + request: Optional[Union[browser_service.ListBrowsersRequest, dict]] = None, + *, + parent: 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.ListBrowsersPager: + r"""API to retrieve a list of ``Browser`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_list_browsers(): + # Create a client + client = admanager_v1.BrowserServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListBrowsersRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_browsers(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.ListBrowsersRequest, dict]): + The request object. Request object for ``ListBrowsers`` method. + parent (str): + Required. The parent, which owns this collection of + Browsers. Format: ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.services.browser_service.pagers.ListBrowsersPager: + Response object for ListBrowsersRequest containing matching Browser + objects. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, browser_service.ListBrowsersRequest): + request = browser_service.ListBrowsersRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_browsers] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.ListBrowsersPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "BrowserServiceClient": + 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() + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("BrowserServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/pagers.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/pagers.py new file mode 100644 index 000000000000..95173cb5fbe0 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/pagers.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +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 + +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.admanager_v1.types import browser_messages, browser_service + + +class ListBrowsersPager: + """A pager for iterating through ``list_browsers`` requests. + + This class thinly wraps an initial + :class:`google.ads.admanager_v1.types.ListBrowsersResponse` object, and + provides an ``__iter__`` method to iterate through its + ``browsers`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListBrowsers`` requests and continue to iterate + through the ``browsers`` field on the + corresponding responses. + + All the usual :class:`google.ads.admanager_v1.types.ListBrowsersResponse` + 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[..., browser_service.ListBrowsersResponse], + request: browser_service.ListBrowsersRequest, + response: browser_service.ListBrowsersResponse, + *, + 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.admanager_v1.types.ListBrowsersRequest): + The initial request object. + response (google.ads.admanager_v1.types.ListBrowsersResponse): + 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 = browser_service.ListBrowsersRequest(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[browser_service.ListBrowsersResponse]: + 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[browser_messages.Browser]: + for page in self.pages: + yield from page.browsers + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/transports/README.rst b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/transports/README.rst new file mode 100644 index 000000000000..08bf910e6862 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`BrowserServiceTransport` is the ABC for all transports. +- public child `BrowserServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `BrowserServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseBrowserServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `BrowserServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/transports/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/transports/__init__.py new file mode 100644 index 000000000000..a1b9c8891b2d --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/transports/__init__.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 typing import Dict, Type + +from .base import BrowserServiceTransport +from .rest import BrowserServiceRestInterceptor, BrowserServiceRestTransport + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[BrowserServiceTransport]] +_transport_registry["rest"] = BrowserServiceRestTransport + +__all__ = ( + "BrowserServiceTransport", + "BrowserServiceRestTransport", + "BrowserServiceRestInterceptor", +) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/transports/base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/transports/base.py new file mode 100644 index 000000000000..2c555d89de12 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/transports/base.py @@ -0,0 +1,198 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version +from google.ads.admanager_v1.types import browser_messages, browser_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 BrowserServiceTransport(abc.ABC): + """Abstract transport class for BrowserService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/admanager",) + + DEFAULT_HOST: str = "admanager.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: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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_browser: gapic_v1.method.wrap_method( + self.get_browser, + default_timeout=None, + client_info=client_info, + ), + self.list_browsers: gapic_v1.method.wrap_method( + self.list_browsers, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + 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_browser( + self, + ) -> Callable[ + [browser_service.GetBrowserRequest], + Union[browser_messages.Browser, Awaitable[browser_messages.Browser]], + ]: + raise NotImplementedError() + + @property + def list_browsers( + self, + ) -> Callable[ + [browser_service.ListBrowsersRequest], + Union[ + browser_service.ListBrowsersResponse, + Awaitable[browser_service.ListBrowsersResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("BrowserServiceTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/transports/rest.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/transports/rest.py new file mode 100644 index 000000000000..b503188825a7 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/transports/rest.py @@ -0,0 +1,771 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.ads.admanager_v1.types import browser_messages, browser_service + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseBrowserServiceRestTransport + +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 = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class BrowserServiceRestInterceptor: + """Interceptor for BrowserService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the BrowserServiceRestTransport. + + .. code-block:: python + class MyCustomBrowserServiceInterceptor(BrowserServiceRestInterceptor): + def pre_get_browser(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_browser(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_browsers(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_browsers(self, response): + logging.log(f"Received response: {response}") + return response + + transport = BrowserServiceRestTransport(interceptor=MyCustomBrowserServiceInterceptor()) + client = BrowserServiceClient(transport=transport) + + + """ + + def pre_get_browser( + self, + request: browser_service.GetBrowserRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + browser_service.GetBrowserRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_browser + + Override in a subclass to manipulate the request or metadata + before they are sent to the BrowserService server. + """ + return request, metadata + + def post_get_browser( + self, response: browser_messages.Browser + ) -> browser_messages.Browser: + """Post-rpc interceptor for get_browser + + DEPRECATED. Please use the `post_get_browser_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the BrowserService server but before + it is returned to user code. This `post_get_browser` interceptor runs + before the `post_get_browser_with_metadata` interceptor. + """ + return response + + def post_get_browser_with_metadata( + self, + response: browser_messages.Browser, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[browser_messages.Browser, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_browser + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the BrowserService server but before it is returned to user code. + + We recommend only using this `post_get_browser_with_metadata` + interceptor in new development instead of the `post_get_browser` interceptor. + When both interceptors are used, this `post_get_browser_with_metadata` interceptor runs after the + `post_get_browser` interceptor. The (possibly modified) response returned by + `post_get_browser` will be passed to + `post_get_browser_with_metadata`. + """ + return response, metadata + + def pre_list_browsers( + self, + request: browser_service.ListBrowsersRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + browser_service.ListBrowsersRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for list_browsers + + Override in a subclass to manipulate the request or metadata + before they are sent to the BrowserService server. + """ + return request, metadata + + def post_list_browsers( + self, response: browser_service.ListBrowsersResponse + ) -> browser_service.ListBrowsersResponse: + """Post-rpc interceptor for list_browsers + + DEPRECATED. Please use the `post_list_browsers_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the BrowserService server but before + it is returned to user code. This `post_list_browsers` interceptor runs + before the `post_list_browsers_with_metadata` interceptor. + """ + return response + + def post_list_browsers_with_metadata( + self, + response: browser_service.ListBrowsersResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + browser_service.ListBrowsersResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_browsers + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the BrowserService server but before it is returned to user code. + + We recommend only using this `post_list_browsers_with_metadata` + interceptor in new development instead of the `post_list_browsers` interceptor. + When both interceptors are used, this `post_list_browsers_with_metadata` interceptor runs after the + `post_list_browsers` interceptor. The (possibly modified) response returned by + `post_list_browsers` will be passed to + `post_list_browsers_with_metadata`. + """ + return response, metadata + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the BrowserService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the BrowserService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class BrowserServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: BrowserServiceRestInterceptor + + +class BrowserServiceRestTransport(_BaseBrowserServiceRestTransport): + """REST backend synchronous transport for BrowserService. + + Provides methods for handling ``Browser`` objects. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[BrowserServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or BrowserServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _GetBrowser( + _BaseBrowserServiceRestTransport._BaseGetBrowser, BrowserServiceRestStub + ): + def __hash__(self): + return hash("BrowserServiceRestTransport.GetBrowser") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: browser_service.GetBrowserRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> browser_messages.Browser: + r"""Call the get browser method over HTTP. + + Args: + request (~.browser_service.GetBrowserRequest): + The request object. Request object for ``GetBrowser`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.browser_messages.Browser: + Represents a browser, including its + version. + + """ + + http_options = ( + _BaseBrowserServiceRestTransport._BaseGetBrowser._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_browser(request, metadata) + transcoded_request = _BaseBrowserServiceRestTransport._BaseGetBrowser._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = ( + _BaseBrowserServiceRestTransport._BaseGetBrowser._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.BrowserServiceClient.GetBrowser", + extra={ + "serviceName": "google.ads.admanager.v1.BrowserService", + "rpcName": "GetBrowser", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = BrowserServiceRestTransport._GetBrowser._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = browser_messages.Browser() + pb_resp = browser_messages.Browser.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_browser(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_browser_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = browser_messages.Browser.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.BrowserServiceClient.get_browser", + extra={ + "serviceName": "google.ads.admanager.v1.BrowserService", + "rpcName": "GetBrowser", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListBrowsers( + _BaseBrowserServiceRestTransport._BaseListBrowsers, BrowserServiceRestStub + ): + def __hash__(self): + return hash("BrowserServiceRestTransport.ListBrowsers") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: browser_service.ListBrowsersRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> browser_service.ListBrowsersResponse: + r"""Call the list browsers method over HTTP. + + Args: + request (~.browser_service.ListBrowsersRequest): + The request object. Request object for ``ListBrowsers`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.browser_service.ListBrowsersResponse: + Response object for ``ListBrowsersRequest`` containing + matching ``Browser`` objects. + + """ + + http_options = ( + _BaseBrowserServiceRestTransport._BaseListBrowsers._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_browsers(request, metadata) + transcoded_request = _BaseBrowserServiceRestTransport._BaseListBrowsers._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseBrowserServiceRestTransport._BaseListBrowsers._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.BrowserServiceClient.ListBrowsers", + extra={ + "serviceName": "google.ads.admanager.v1.BrowserService", + "rpcName": "ListBrowsers", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = BrowserServiceRestTransport._ListBrowsers._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = browser_service.ListBrowsersResponse() + pb_resp = browser_service.ListBrowsersResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_browsers(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_browsers_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = browser_service.ListBrowsersResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.BrowserServiceClient.list_browsers", + extra={ + "serviceName": "google.ads.admanager.v1.BrowserService", + "rpcName": "ListBrowsers", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def get_browser( + self, + ) -> Callable[[browser_service.GetBrowserRequest], browser_messages.Browser]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetBrowser(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_browsers( + self, + ) -> Callable[ + [browser_service.ListBrowsersRequest], browser_service.ListBrowsersResponse + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListBrowsers(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseBrowserServiceRestTransport._BaseGetOperation, BrowserServiceRestStub + ): + def __hash__(self): + return hash("BrowserServiceRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = ( + _BaseBrowserServiceRestTransport._BaseGetOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = _BaseBrowserServiceRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseBrowserServiceRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.BrowserServiceClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.BrowserService", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = BrowserServiceRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.BrowserServiceAsyncClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.BrowserService", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("BrowserServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/transports/rest_base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/transports/rest_base.py new file mode 100644 index 000000000000..4e4b7ca9c627 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/browser_service/transports/rest_base.py @@ -0,0 +1,211 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.ads.admanager_v1.types import browser_messages, browser_service + +from .base import DEFAULT_CLIENT_INFO, BrowserServiceTransport + + +class _BaseBrowserServiceRestTransport(BrowserServiceTransport): + """Base REST backend transport for BrowserService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetBrowser: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/browsers/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = browser_service.GetBrowserRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseBrowserServiceRestTransport._BaseGetBrowser._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListBrowsers: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=networks/*}/browsers", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = browser_service.ListBrowsersRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseBrowserServiceRestTransport._BaseListBrowsers._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/operations/reports/runs/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseBrowserServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/__init__.py new file mode 100644 index 000000000000..696f69586d02 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CmsMetadataKeyServiceClient + +__all__ = ("CmsMetadataKeyServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/client.py new file mode 100644 index 000000000000..2a996751db75 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/client.py @@ -0,0 +1,1049 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +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.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version + +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.longrunning import operations_pb2 # type: ignore + +from google.ads.admanager_v1.services.cms_metadata_key_service import pagers +from google.ads.admanager_v1.types import ( + cms_metadata_key_enums, + cms_metadata_key_messages, + cms_metadata_key_service, +) + +from .transports.base import DEFAULT_CLIENT_INFO, CmsMetadataKeyServiceTransport +from .transports.rest import CmsMetadataKeyServiceRestTransport + + +class CmsMetadataKeyServiceClientMeta(type): + """Metaclass for the CmsMetadataKeyService 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[CmsMetadataKeyServiceTransport]] + _transport_registry["rest"] = CmsMetadataKeyServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CmsMetadataKeyServiceTransport]: + """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 CmsMetadataKeyServiceClient(metaclass=CmsMetadataKeyServiceClientMeta): + """Provides methods for handling ``CmsMetadataKey`` objects.""" + + @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 = "admanager.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "admanager.{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: + CmsMetadataKeyServiceClient: 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: + CmsMetadataKeyServiceClient: 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) -> CmsMetadataKeyServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CmsMetadataKeyServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def cms_metadata_key_path( + network_code: str, + cms_metadata_key: str, + ) -> str: + """Returns a fully-qualified cms_metadata_key string.""" + return "networks/{network_code}/cmsMetadataKeys/{cms_metadata_key}".format( + network_code=network_code, + cms_metadata_key=cms_metadata_key, + ) + + @staticmethod + def parse_cms_metadata_key_path(path: str) -> Dict[str, str]: + """Parses a cms_metadata_key path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/cmsMetadataKeys/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def network_path( + network_code: str, + ) -> str: + """Returns a fully-qualified network string.""" + return "networks/{network_code}".format( + network_code=network_code, + ) + + @staticmethod + def parse_network_path(path: str) -> Dict[str, str]: + """Parses a network path into its component segments.""" + m = re.match(r"^networks/(?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 = CmsMetadataKeyServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CmsMetadataKeyServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + CmsMetadataKeyServiceClient._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 = CmsMetadataKeyServiceClient._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, + CmsMetadataKeyServiceTransport, + Callable[..., CmsMetadataKeyServiceTransport], + ] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the cms metadata key 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,CmsMetadataKeyServiceTransport,Callable[..., CmsMetadataKeyServiceTransport]]]): + 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 CmsMetadataKeyServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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, + ) = CmsMetadataKeyServiceClient._read_environment_variables() + self._client_cert_source = CmsMetadataKeyServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = CmsMetadataKeyServiceClient._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, CmsMetadataKeyServiceTransport) + if transport_provided: + # transport is a CmsMetadataKeyServiceTransport 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(CmsMetadataKeyServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CmsMetadataKeyServiceClient._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[CmsMetadataKeyServiceTransport], + Callable[..., CmsMetadataKeyServiceTransport], + ] = ( + CmsMetadataKeyServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., CmsMetadataKeyServiceTransport], 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.admanager_v1.CmsMetadataKeyServiceClient`.", + extra={ + "serviceName": "google.ads.admanager.v1.CmsMetadataKeyService", + "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.admanager.v1.CmsMetadataKeyService", + "credentialsType": None, + }, + ) + + def get_cms_metadata_key( + self, + request: Optional[ + Union[cms_metadata_key_service.GetCmsMetadataKeyRequest, dict] + ] = None, + *, + 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]]] = (), + ) -> cms_metadata_key_messages.CmsMetadataKey: + r"""API to retrieve a ``CmsMetadataKey`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_get_cms_metadata_key(): + # Create a client + client = admanager_v1.CmsMetadataKeyServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetCmsMetadataKeyRequest( + name="name_value", + ) + + # Make the request + response = client.get_cms_metadata_key(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.GetCmsMetadataKeyRequest, dict]): + The request object. Request object for ``GetCmsMetadataKey`` method. + name (str): + Required. The resource name of the CmsMetadataKey. + Format: + ``networks/{network_code}/cmsMetadataKeys/{cms_metadata_key_id}`` + + This corresponds to the ``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.admanager_v1.types.CmsMetadataKey: + Key associated with a piece of + content from a publisher's CMS. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, cms_metadata_key_service.GetCmsMetadataKeyRequest): + request = cms_metadata_key_service.GetCmsMetadataKeyRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_cms_metadata_key] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_cms_metadata_keys( + self, + request: Optional[ + Union[cms_metadata_key_service.ListCmsMetadataKeysRequest, dict] + ] = None, + *, + parent: 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.ListCmsMetadataKeysPager: + r"""API to retrieve a list of ``CmsMetadataKey`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_list_cms_metadata_keys(): + # Create a client + client = admanager_v1.CmsMetadataKeyServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListCmsMetadataKeysRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_cms_metadata_keys(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.ListCmsMetadataKeysRequest, dict]): + The request object. Request object for ``ListCmsMetadataKeys`` method. + parent (str): + Required. The parent, which owns this collection of + CmsMetadataKeys. Format: ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.services.cms_metadata_key_service.pagers.ListCmsMetadataKeysPager: + Response object for ListCmsMetadataKeysRequest containing matching + CmsMetadataKey objects. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, cms_metadata_key_service.ListCmsMetadataKeysRequest): + request = cms_metadata_key_service.ListCmsMetadataKeysRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_cms_metadata_keys] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.ListCmsMetadataKeysPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CmsMetadataKeyServiceClient": + 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() + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CmsMetadataKeyServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/pagers.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/pagers.py new file mode 100644 index 000000000000..ef1178a06532 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/pagers.py @@ -0,0 +1,120 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +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 + +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.admanager_v1.types import ( + cms_metadata_key_messages, + cms_metadata_key_service, +) + + +class ListCmsMetadataKeysPager: + """A pager for iterating through ``list_cms_metadata_keys`` requests. + + This class thinly wraps an initial + :class:`google.ads.admanager_v1.types.ListCmsMetadataKeysResponse` object, and + provides an ``__iter__`` method to iterate through its + ``cms_metadata_keys`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListCmsMetadataKeys`` requests and continue to iterate + through the ``cms_metadata_keys`` field on the + corresponding responses. + + All the usual :class:`google.ads.admanager_v1.types.ListCmsMetadataKeysResponse` + 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[..., cms_metadata_key_service.ListCmsMetadataKeysResponse], + request: cms_metadata_key_service.ListCmsMetadataKeysRequest, + response: cms_metadata_key_service.ListCmsMetadataKeysResponse, + *, + 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.admanager_v1.types.ListCmsMetadataKeysRequest): + The initial request object. + response (google.ads.admanager_v1.types.ListCmsMetadataKeysResponse): + 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 = cms_metadata_key_service.ListCmsMetadataKeysRequest(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[cms_metadata_key_service.ListCmsMetadataKeysResponse]: + 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[cms_metadata_key_messages.CmsMetadataKey]: + for page in self.pages: + yield from page.cms_metadata_keys + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/transports/README.rst b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/transports/README.rst new file mode 100644 index 000000000000..5c39bcc3649b --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`CmsMetadataKeyServiceTransport` is the ABC for all transports. +- public child `CmsMetadataKeyServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `CmsMetadataKeyServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseCmsMetadataKeyServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `CmsMetadataKeyServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/transports/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/transports/__init__.py new file mode 100644 index 000000000000..8df01714ef69 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/transports/__init__.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 typing import Dict, Type + +from .base import CmsMetadataKeyServiceTransport +from .rest import ( + CmsMetadataKeyServiceRestInterceptor, + CmsMetadataKeyServiceRestTransport, +) + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CmsMetadataKeyServiceTransport]] +_transport_registry["rest"] = CmsMetadataKeyServiceRestTransport + +__all__ = ( + "CmsMetadataKeyServiceTransport", + "CmsMetadataKeyServiceRestTransport", + "CmsMetadataKeyServiceRestInterceptor", +) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/transports/base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/transports/base.py new file mode 100644 index 000000000000..40a4057af764 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/transports/base.py @@ -0,0 +1,204 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version +from google.ads.admanager_v1.types import ( + cms_metadata_key_messages, + cms_metadata_key_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 CmsMetadataKeyServiceTransport(abc.ABC): + """Abstract transport class for CmsMetadataKeyService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/admanager",) + + DEFAULT_HOST: str = "admanager.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: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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_cms_metadata_key: gapic_v1.method.wrap_method( + self.get_cms_metadata_key, + default_timeout=None, + client_info=client_info, + ), + self.list_cms_metadata_keys: gapic_v1.method.wrap_method( + self.list_cms_metadata_keys, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + 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_cms_metadata_key( + self, + ) -> Callable[ + [cms_metadata_key_service.GetCmsMetadataKeyRequest], + Union[ + cms_metadata_key_messages.CmsMetadataKey, + Awaitable[cms_metadata_key_messages.CmsMetadataKey], + ], + ]: + raise NotImplementedError() + + @property + def list_cms_metadata_keys( + self, + ) -> Callable[ + [cms_metadata_key_service.ListCmsMetadataKeysRequest], + Union[ + cms_metadata_key_service.ListCmsMetadataKeysResponse, + Awaitable[cms_metadata_key_service.ListCmsMetadataKeysResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CmsMetadataKeyServiceTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/transports/rest.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/transports/rest.py new file mode 100644 index 000000000000..ba7cc92b7378 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/transports/rest.py @@ -0,0 +1,797 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.ads.admanager_v1.types import ( + cms_metadata_key_messages, + cms_metadata_key_service, +) + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseCmsMetadataKeyServiceRestTransport + +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 = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CmsMetadataKeyServiceRestInterceptor: + """Interceptor for CmsMetadataKeyService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the CmsMetadataKeyServiceRestTransport. + + .. code-block:: python + class MyCustomCmsMetadataKeyServiceInterceptor(CmsMetadataKeyServiceRestInterceptor): + def pre_get_cms_metadata_key(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_cms_metadata_key(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_cms_metadata_keys(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_cms_metadata_keys(self, response): + logging.log(f"Received response: {response}") + return response + + transport = CmsMetadataKeyServiceRestTransport(interceptor=MyCustomCmsMetadataKeyServiceInterceptor()) + client = CmsMetadataKeyServiceClient(transport=transport) + + + """ + + def pre_get_cms_metadata_key( + self, + request: cms_metadata_key_service.GetCmsMetadataKeyRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cms_metadata_key_service.GetCmsMetadataKeyRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for get_cms_metadata_key + + Override in a subclass to manipulate the request or metadata + before they are sent to the CmsMetadataKeyService server. + """ + return request, metadata + + def post_get_cms_metadata_key( + self, response: cms_metadata_key_messages.CmsMetadataKey + ) -> cms_metadata_key_messages.CmsMetadataKey: + """Post-rpc interceptor for get_cms_metadata_key + + DEPRECATED. Please use the `post_get_cms_metadata_key_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the CmsMetadataKeyService server but before + it is returned to user code. This `post_get_cms_metadata_key` interceptor runs + before the `post_get_cms_metadata_key_with_metadata` interceptor. + """ + return response + + def post_get_cms_metadata_key_with_metadata( + self, + response: cms_metadata_key_messages.CmsMetadataKey, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cms_metadata_key_messages.CmsMetadataKey, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for get_cms_metadata_key + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CmsMetadataKeyService server but before it is returned to user code. + + We recommend only using this `post_get_cms_metadata_key_with_metadata` + interceptor in new development instead of the `post_get_cms_metadata_key` interceptor. + When both interceptors are used, this `post_get_cms_metadata_key_with_metadata` interceptor runs after the + `post_get_cms_metadata_key` interceptor. The (possibly modified) response returned by + `post_get_cms_metadata_key` will be passed to + `post_get_cms_metadata_key_with_metadata`. + """ + return response, metadata + + def pre_list_cms_metadata_keys( + self, + request: cms_metadata_key_service.ListCmsMetadataKeysRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cms_metadata_key_service.ListCmsMetadataKeysRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for list_cms_metadata_keys + + Override in a subclass to manipulate the request or metadata + before they are sent to the CmsMetadataKeyService server. + """ + return request, metadata + + def post_list_cms_metadata_keys( + self, response: cms_metadata_key_service.ListCmsMetadataKeysResponse + ) -> cms_metadata_key_service.ListCmsMetadataKeysResponse: + """Post-rpc interceptor for list_cms_metadata_keys + + DEPRECATED. Please use the `post_list_cms_metadata_keys_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the CmsMetadataKeyService server but before + it is returned to user code. This `post_list_cms_metadata_keys` interceptor runs + before the `post_list_cms_metadata_keys_with_metadata` interceptor. + """ + return response + + def post_list_cms_metadata_keys_with_metadata( + self, + response: cms_metadata_key_service.ListCmsMetadataKeysResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cms_metadata_key_service.ListCmsMetadataKeysResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_cms_metadata_keys + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CmsMetadataKeyService server but before it is returned to user code. + + We recommend only using this `post_list_cms_metadata_keys_with_metadata` + interceptor in new development instead of the `post_list_cms_metadata_keys` interceptor. + When both interceptors are used, this `post_list_cms_metadata_keys_with_metadata` interceptor runs after the + `post_list_cms_metadata_keys` interceptor. The (possibly modified) response returned by + `post_list_cms_metadata_keys` will be passed to + `post_list_cms_metadata_keys_with_metadata`. + """ + return response, metadata + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the CmsMetadataKeyService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the CmsMetadataKeyService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class CmsMetadataKeyServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: CmsMetadataKeyServiceRestInterceptor + + +class CmsMetadataKeyServiceRestTransport(_BaseCmsMetadataKeyServiceRestTransport): + """REST backend synchronous transport for CmsMetadataKeyService. + + Provides methods for handling ``CmsMetadataKey`` objects. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[CmsMetadataKeyServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or CmsMetadataKeyServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _GetCmsMetadataKey( + _BaseCmsMetadataKeyServiceRestTransport._BaseGetCmsMetadataKey, + CmsMetadataKeyServiceRestStub, + ): + def __hash__(self): + return hash("CmsMetadataKeyServiceRestTransport.GetCmsMetadataKey") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: cms_metadata_key_service.GetCmsMetadataKeyRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> cms_metadata_key_messages.CmsMetadataKey: + r"""Call the get cms metadata key method over HTTP. + + Args: + request (~.cms_metadata_key_service.GetCmsMetadataKeyRequest): + The request object. Request object for ``GetCmsMetadataKey`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.cms_metadata_key_messages.CmsMetadataKey: + Key associated with a piece of + content from a publisher's CMS. + + """ + + http_options = ( + _BaseCmsMetadataKeyServiceRestTransport._BaseGetCmsMetadataKey._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_cms_metadata_key( + request, metadata + ) + transcoded_request = _BaseCmsMetadataKeyServiceRestTransport._BaseGetCmsMetadataKey._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseCmsMetadataKeyServiceRestTransport._BaseGetCmsMetadataKey._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.CmsMetadataKeyServiceClient.GetCmsMetadataKey", + extra={ + "serviceName": "google.ads.admanager.v1.CmsMetadataKeyService", + "rpcName": "GetCmsMetadataKey", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + CmsMetadataKeyServiceRestTransport._GetCmsMetadataKey._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = cms_metadata_key_messages.CmsMetadataKey() + pb_resp = cms_metadata_key_messages.CmsMetadataKey.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_cms_metadata_key(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_cms_metadata_key_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = cms_metadata_key_messages.CmsMetadataKey.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.CmsMetadataKeyServiceClient.get_cms_metadata_key", + extra={ + "serviceName": "google.ads.admanager.v1.CmsMetadataKeyService", + "rpcName": "GetCmsMetadataKey", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListCmsMetadataKeys( + _BaseCmsMetadataKeyServiceRestTransport._BaseListCmsMetadataKeys, + CmsMetadataKeyServiceRestStub, + ): + def __hash__(self): + return hash("CmsMetadataKeyServiceRestTransport.ListCmsMetadataKeys") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: cms_metadata_key_service.ListCmsMetadataKeysRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> cms_metadata_key_service.ListCmsMetadataKeysResponse: + r"""Call the list cms metadata keys method over HTTP. + + Args: + request (~.cms_metadata_key_service.ListCmsMetadataKeysRequest): + The request object. Request object for ``ListCmsMetadataKeys`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.cms_metadata_key_service.ListCmsMetadataKeysResponse: + Response object for ``ListCmsMetadataKeysRequest`` + containing matching ``CmsMetadataKey`` objects. + + """ + + http_options = ( + _BaseCmsMetadataKeyServiceRestTransport._BaseListCmsMetadataKeys._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_cms_metadata_keys( + request, metadata + ) + transcoded_request = _BaseCmsMetadataKeyServiceRestTransport._BaseListCmsMetadataKeys._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseCmsMetadataKeyServiceRestTransport._BaseListCmsMetadataKeys._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.CmsMetadataKeyServiceClient.ListCmsMetadataKeys", + extra={ + "serviceName": "google.ads.admanager.v1.CmsMetadataKeyService", + "rpcName": "ListCmsMetadataKeys", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + CmsMetadataKeyServiceRestTransport._ListCmsMetadataKeys._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = cms_metadata_key_service.ListCmsMetadataKeysResponse() + pb_resp = cms_metadata_key_service.ListCmsMetadataKeysResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_cms_metadata_keys(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_cms_metadata_keys_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + cms_metadata_key_service.ListCmsMetadataKeysResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.CmsMetadataKeyServiceClient.list_cms_metadata_keys", + extra={ + "serviceName": "google.ads.admanager.v1.CmsMetadataKeyService", + "rpcName": "ListCmsMetadataKeys", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def get_cms_metadata_key( + self, + ) -> Callable[ + [cms_metadata_key_service.GetCmsMetadataKeyRequest], + cms_metadata_key_messages.CmsMetadataKey, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetCmsMetadataKey(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_cms_metadata_keys( + self, + ) -> Callable[ + [cms_metadata_key_service.ListCmsMetadataKeysRequest], + cms_metadata_key_service.ListCmsMetadataKeysResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListCmsMetadataKeys(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseCmsMetadataKeyServiceRestTransport._BaseGetOperation, + CmsMetadataKeyServiceRestStub, + ): + def __hash__(self): + return hash("CmsMetadataKeyServiceRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = ( + _BaseCmsMetadataKeyServiceRestTransport._BaseGetOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = _BaseCmsMetadataKeyServiceRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseCmsMetadataKeyServiceRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.CmsMetadataKeyServiceClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.CmsMetadataKeyService", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = CmsMetadataKeyServiceRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.CmsMetadataKeyServiceAsyncClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.CmsMetadataKeyService", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("CmsMetadataKeyServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/transports/rest_base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/transports/rest_base.py new file mode 100644 index 000000000000..13f732f8397c --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_key_service/transports/rest_base.py @@ -0,0 +1,214 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.ads.admanager_v1.types import ( + cms_metadata_key_messages, + cms_metadata_key_service, +) + +from .base import DEFAULT_CLIENT_INFO, CmsMetadataKeyServiceTransport + + +class _BaseCmsMetadataKeyServiceRestTransport(CmsMetadataKeyServiceTransport): + """Base REST backend transport for CmsMetadataKeyService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetCmsMetadataKey: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/cmsMetadataKeys/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = cms_metadata_key_service.GetCmsMetadataKeyRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseCmsMetadataKeyServiceRestTransport._BaseGetCmsMetadataKey._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListCmsMetadataKeys: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=networks/*}/cmsMetadataKeys", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = cms_metadata_key_service.ListCmsMetadataKeysRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseCmsMetadataKeyServiceRestTransport._BaseListCmsMetadataKeys._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/operations/reports/runs/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseCmsMetadataKeyServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/__init__.py new file mode 100644 index 000000000000..d5777fed44c7 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CmsMetadataValueServiceClient + +__all__ = ("CmsMetadataValueServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/client.py new file mode 100644 index 000000000000..2212bda9d2a9 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/client.py @@ -0,0 +1,1075 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +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.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version + +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.longrunning import operations_pb2 # type: ignore + +from google.ads.admanager_v1.services.cms_metadata_value_service import pagers +from google.ads.admanager_v1.types import ( + cms_metadata_value_enums, + cms_metadata_value_messages, + cms_metadata_value_service, +) + +from .transports.base import DEFAULT_CLIENT_INFO, CmsMetadataValueServiceTransport +from .transports.rest import CmsMetadataValueServiceRestTransport + + +class CmsMetadataValueServiceClientMeta(type): + """Metaclass for the CmsMetadataValueService 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[CmsMetadataValueServiceTransport]] + _transport_registry["rest"] = CmsMetadataValueServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CmsMetadataValueServiceTransport]: + """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 CmsMetadataValueServiceClient(metaclass=CmsMetadataValueServiceClientMeta): + """Provides methods for handling ``CmsMetadataValue`` objects.""" + + @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 = "admanager.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "admanager.{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: + CmsMetadataValueServiceClient: 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: + CmsMetadataValueServiceClient: 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) -> CmsMetadataValueServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CmsMetadataValueServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def cms_metadata_key_path( + network_code: str, + cms_metadata_key: str, + ) -> str: + """Returns a fully-qualified cms_metadata_key string.""" + return "networks/{network_code}/cmsMetadataKeys/{cms_metadata_key}".format( + network_code=network_code, + cms_metadata_key=cms_metadata_key, + ) + + @staticmethod + def parse_cms_metadata_key_path(path: str) -> Dict[str, str]: + """Parses a cms_metadata_key path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/cmsMetadataKeys/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def cms_metadata_value_path( + network_code: str, + cms_metadata_value: str, + ) -> str: + """Returns a fully-qualified cms_metadata_value string.""" + return "networks/{network_code}/cmsMetadataValues/{cms_metadata_value}".format( + network_code=network_code, + cms_metadata_value=cms_metadata_value, + ) + + @staticmethod + def parse_cms_metadata_value_path(path: str) -> Dict[str, str]: + """Parses a cms_metadata_value path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/cmsMetadataValues/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def network_path( + network_code: str, + ) -> str: + """Returns a fully-qualified network string.""" + return "networks/{network_code}".format( + network_code=network_code, + ) + + @staticmethod + def parse_network_path(path: str) -> Dict[str, str]: + """Parses a network path into its component segments.""" + m = re.match(r"^networks/(?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 = CmsMetadataValueServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CmsMetadataValueServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + CmsMetadataValueServiceClient._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 = CmsMetadataValueServiceClient._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, + CmsMetadataValueServiceTransport, + Callable[..., CmsMetadataValueServiceTransport], + ] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the cms metadata value 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,CmsMetadataValueServiceTransport,Callable[..., CmsMetadataValueServiceTransport]]]): + 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 CmsMetadataValueServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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, + ) = CmsMetadataValueServiceClient._read_environment_variables() + self._client_cert_source = ( + CmsMetadataValueServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = CmsMetadataValueServiceClient._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, CmsMetadataValueServiceTransport) + if transport_provided: + # transport is a CmsMetadataValueServiceTransport 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(CmsMetadataValueServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CmsMetadataValueServiceClient._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[CmsMetadataValueServiceTransport], + Callable[..., CmsMetadataValueServiceTransport], + ] = ( + CmsMetadataValueServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., CmsMetadataValueServiceTransport], 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.admanager_v1.CmsMetadataValueServiceClient`.", + extra={ + "serviceName": "google.ads.admanager.v1.CmsMetadataValueService", + "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.admanager.v1.CmsMetadataValueService", + "credentialsType": None, + }, + ) + + def get_cms_metadata_value( + self, + request: Optional[ + Union[cms_metadata_value_service.GetCmsMetadataValueRequest, dict] + ] = None, + *, + 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]]] = (), + ) -> cms_metadata_value_messages.CmsMetadataValue: + r"""API to retrieve a ``CmsMetadataKey`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_get_cms_metadata_value(): + # Create a client + client = admanager_v1.CmsMetadataValueServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetCmsMetadataValueRequest( + name="name_value", + ) + + # Make the request + response = client.get_cms_metadata_value(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.GetCmsMetadataValueRequest, dict]): + The request object. Request object for ``GetCmsMetadataValue`` method. + name (str): + Required. The resource name of the CmsMetadataKey. + Format: + ``networks/{network_code}/cmsMetadataValues/{cms_metadata_value_id}`` + + This corresponds to the ``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.admanager_v1.types.CmsMetadataValue: + Key value pair associated with a + piece of content from a publisher's CMS. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, cms_metadata_value_service.GetCmsMetadataValueRequest + ): + request = cms_metadata_value_service.GetCmsMetadataValueRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_cms_metadata_value] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_cms_metadata_values( + self, + request: Optional[ + Union[cms_metadata_value_service.ListCmsMetadataValuesRequest, dict] + ] = None, + *, + parent: 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.ListCmsMetadataValuesPager: + r"""API to retrieve a list of ``CmsMetadataValue`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_list_cms_metadata_values(): + # Create a client + client = admanager_v1.CmsMetadataValueServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListCmsMetadataValuesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_cms_metadata_values(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.ListCmsMetadataValuesRequest, dict]): + The request object. Request object for ``ListCmsMetadataValues`` method. + parent (str): + Required. The parent, which owns this collection of + CmsMetadataValues. Format: ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.services.cms_metadata_value_service.pagers.ListCmsMetadataValuesPager: + Response object for ListCmsMetadataValuesRequest containing matching + CmsMetadataValue objects. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, cms_metadata_value_service.ListCmsMetadataValuesRequest + ): + request = cms_metadata_value_service.ListCmsMetadataValuesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_cms_metadata_values] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.ListCmsMetadataValuesPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CmsMetadataValueServiceClient": + 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() + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CmsMetadataValueServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/pagers.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/pagers.py new file mode 100644 index 000000000000..bc68d27c7c58 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/pagers.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 typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +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 + +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.admanager_v1.types import ( + cms_metadata_value_messages, + cms_metadata_value_service, +) + + +class ListCmsMetadataValuesPager: + """A pager for iterating through ``list_cms_metadata_values`` requests. + + This class thinly wraps an initial + :class:`google.ads.admanager_v1.types.ListCmsMetadataValuesResponse` object, and + provides an ``__iter__`` method to iterate through its + ``cms_metadata_values`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListCmsMetadataValues`` requests and continue to iterate + through the ``cms_metadata_values`` field on the + corresponding responses. + + All the usual :class:`google.ads.admanager_v1.types.ListCmsMetadataValuesResponse` + 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[..., cms_metadata_value_service.ListCmsMetadataValuesResponse], + request: cms_metadata_value_service.ListCmsMetadataValuesRequest, + response: cms_metadata_value_service.ListCmsMetadataValuesResponse, + *, + 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.admanager_v1.types.ListCmsMetadataValuesRequest): + The initial request object. + response (google.ads.admanager_v1.types.ListCmsMetadataValuesResponse): + 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 = cms_metadata_value_service.ListCmsMetadataValuesRequest(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[cms_metadata_value_service.ListCmsMetadataValuesResponse]: + 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[cms_metadata_value_messages.CmsMetadataValue]: + for page in self.pages: + yield from page.cms_metadata_values + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/transports/README.rst b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/transports/README.rst new file mode 100644 index 000000000000..2c2ac8792a09 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`CmsMetadataValueServiceTransport` is the ABC for all transports. +- public child `CmsMetadataValueServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `CmsMetadataValueServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseCmsMetadataValueServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `CmsMetadataValueServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/transports/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/transports/__init__.py new file mode 100644 index 000000000000..03c87919081d --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/transports/__init__.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 typing import Dict, Type + +from .base import CmsMetadataValueServiceTransport +from .rest import ( + CmsMetadataValueServiceRestInterceptor, + CmsMetadataValueServiceRestTransport, +) + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CmsMetadataValueServiceTransport]] +_transport_registry["rest"] = CmsMetadataValueServiceRestTransport + +__all__ = ( + "CmsMetadataValueServiceTransport", + "CmsMetadataValueServiceRestTransport", + "CmsMetadataValueServiceRestInterceptor", +) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/transports/base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/transports/base.py new file mode 100644 index 000000000000..c857dd00c112 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/transports/base.py @@ -0,0 +1,204 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version +from google.ads.admanager_v1.types import ( + cms_metadata_value_messages, + cms_metadata_value_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 CmsMetadataValueServiceTransport(abc.ABC): + """Abstract transport class for CmsMetadataValueService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/admanager",) + + DEFAULT_HOST: str = "admanager.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: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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_cms_metadata_value: gapic_v1.method.wrap_method( + self.get_cms_metadata_value, + default_timeout=None, + client_info=client_info, + ), + self.list_cms_metadata_values: gapic_v1.method.wrap_method( + self.list_cms_metadata_values, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + 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_cms_metadata_value( + self, + ) -> Callable[ + [cms_metadata_value_service.GetCmsMetadataValueRequest], + Union[ + cms_metadata_value_messages.CmsMetadataValue, + Awaitable[cms_metadata_value_messages.CmsMetadataValue], + ], + ]: + raise NotImplementedError() + + @property + def list_cms_metadata_values( + self, + ) -> Callable[ + [cms_metadata_value_service.ListCmsMetadataValuesRequest], + Union[ + cms_metadata_value_service.ListCmsMetadataValuesResponse, + Awaitable[cms_metadata_value_service.ListCmsMetadataValuesResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CmsMetadataValueServiceTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/transports/rest.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/transports/rest.py new file mode 100644 index 000000000000..e17ef914e113 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/transports/rest.py @@ -0,0 +1,793 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.ads.admanager_v1.types import ( + cms_metadata_value_messages, + cms_metadata_value_service, +) + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseCmsMetadataValueServiceRestTransport + +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 = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CmsMetadataValueServiceRestInterceptor: + """Interceptor for CmsMetadataValueService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the CmsMetadataValueServiceRestTransport. + + .. code-block:: python + class MyCustomCmsMetadataValueServiceInterceptor(CmsMetadataValueServiceRestInterceptor): + def pre_get_cms_metadata_value(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_cms_metadata_value(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_cms_metadata_values(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_cms_metadata_values(self, response): + logging.log(f"Received response: {response}") + return response + + transport = CmsMetadataValueServiceRestTransport(interceptor=MyCustomCmsMetadataValueServiceInterceptor()) + client = CmsMetadataValueServiceClient(transport=transport) + + + """ + + def pre_get_cms_metadata_value( + self, + request: cms_metadata_value_service.GetCmsMetadataValueRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cms_metadata_value_service.GetCmsMetadataValueRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for get_cms_metadata_value + + Override in a subclass to manipulate the request or metadata + before they are sent to the CmsMetadataValueService server. + """ + return request, metadata + + def post_get_cms_metadata_value( + self, response: cms_metadata_value_messages.CmsMetadataValue + ) -> cms_metadata_value_messages.CmsMetadataValue: + """Post-rpc interceptor for get_cms_metadata_value + + DEPRECATED. Please use the `post_get_cms_metadata_value_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the CmsMetadataValueService server but before + it is returned to user code. This `post_get_cms_metadata_value` interceptor runs + before the `post_get_cms_metadata_value_with_metadata` interceptor. + """ + return response + + def post_get_cms_metadata_value_with_metadata( + self, + response: cms_metadata_value_messages.CmsMetadataValue, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cms_metadata_value_messages.CmsMetadataValue, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for get_cms_metadata_value + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CmsMetadataValueService server but before it is returned to user code. + + We recommend only using this `post_get_cms_metadata_value_with_metadata` + interceptor in new development instead of the `post_get_cms_metadata_value` interceptor. + When both interceptors are used, this `post_get_cms_metadata_value_with_metadata` interceptor runs after the + `post_get_cms_metadata_value` interceptor. The (possibly modified) response returned by + `post_get_cms_metadata_value` will be passed to + `post_get_cms_metadata_value_with_metadata`. + """ + return response, metadata + + def pre_list_cms_metadata_values( + self, + request: cms_metadata_value_service.ListCmsMetadataValuesRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cms_metadata_value_service.ListCmsMetadataValuesRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for list_cms_metadata_values + + Override in a subclass to manipulate the request or metadata + before they are sent to the CmsMetadataValueService server. + """ + return request, metadata + + def post_list_cms_metadata_values( + self, response: cms_metadata_value_service.ListCmsMetadataValuesResponse + ) -> cms_metadata_value_service.ListCmsMetadataValuesResponse: + """Post-rpc interceptor for list_cms_metadata_values + + DEPRECATED. Please use the `post_list_cms_metadata_values_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the CmsMetadataValueService server but before + it is returned to user code. This `post_list_cms_metadata_values` interceptor runs + before the `post_list_cms_metadata_values_with_metadata` interceptor. + """ + return response + + def post_list_cms_metadata_values_with_metadata( + self, + response: cms_metadata_value_service.ListCmsMetadataValuesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cms_metadata_value_service.ListCmsMetadataValuesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_cms_metadata_values + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CmsMetadataValueService server but before it is returned to user code. + + We recommend only using this `post_list_cms_metadata_values_with_metadata` + interceptor in new development instead of the `post_list_cms_metadata_values` interceptor. + When both interceptors are used, this `post_list_cms_metadata_values_with_metadata` interceptor runs after the + `post_list_cms_metadata_values` interceptor. The (possibly modified) response returned by + `post_list_cms_metadata_values` will be passed to + `post_list_cms_metadata_values_with_metadata`. + """ + return response, metadata + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the CmsMetadataValueService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the CmsMetadataValueService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class CmsMetadataValueServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: CmsMetadataValueServiceRestInterceptor + + +class CmsMetadataValueServiceRestTransport(_BaseCmsMetadataValueServiceRestTransport): + """REST backend synchronous transport for CmsMetadataValueService. + + Provides methods for handling ``CmsMetadataValue`` objects. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[CmsMetadataValueServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or CmsMetadataValueServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _GetCmsMetadataValue( + _BaseCmsMetadataValueServiceRestTransport._BaseGetCmsMetadataValue, + CmsMetadataValueServiceRestStub, + ): + def __hash__(self): + return hash("CmsMetadataValueServiceRestTransport.GetCmsMetadataValue") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: cms_metadata_value_service.GetCmsMetadataValueRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> cms_metadata_value_messages.CmsMetadataValue: + r"""Call the get cms metadata value method over HTTP. + + Args: + request (~.cms_metadata_value_service.GetCmsMetadataValueRequest): + The request object. Request object for ``GetCmsMetadataValue`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.cms_metadata_value_messages.CmsMetadataValue: + Key value pair associated with a + piece of content from a publisher's CMS. + + """ + + http_options = ( + _BaseCmsMetadataValueServiceRestTransport._BaseGetCmsMetadataValue._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_cms_metadata_value( + request, metadata + ) + transcoded_request = _BaseCmsMetadataValueServiceRestTransport._BaseGetCmsMetadataValue._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseCmsMetadataValueServiceRestTransport._BaseGetCmsMetadataValue._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.CmsMetadataValueServiceClient.GetCmsMetadataValue", + extra={ + "serviceName": "google.ads.admanager.v1.CmsMetadataValueService", + "rpcName": "GetCmsMetadataValue", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + CmsMetadataValueServiceRestTransport._GetCmsMetadataValue._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = cms_metadata_value_messages.CmsMetadataValue() + pb_resp = cms_metadata_value_messages.CmsMetadataValue.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_cms_metadata_value(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_cms_metadata_value_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + cms_metadata_value_messages.CmsMetadataValue.to_json(response) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.CmsMetadataValueServiceClient.get_cms_metadata_value", + extra={ + "serviceName": "google.ads.admanager.v1.CmsMetadataValueService", + "rpcName": "GetCmsMetadataValue", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListCmsMetadataValues( + _BaseCmsMetadataValueServiceRestTransport._BaseListCmsMetadataValues, + CmsMetadataValueServiceRestStub, + ): + def __hash__(self): + return hash("CmsMetadataValueServiceRestTransport.ListCmsMetadataValues") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: cms_metadata_value_service.ListCmsMetadataValuesRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> cms_metadata_value_service.ListCmsMetadataValuesResponse: + r"""Call the list cms metadata values method over HTTP. + + Args: + request (~.cms_metadata_value_service.ListCmsMetadataValuesRequest): + The request object. Request object for ``ListCmsMetadataValues`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.cms_metadata_value_service.ListCmsMetadataValuesResponse: + Response object for ``ListCmsMetadataValuesRequest`` + containing matching ``CmsMetadataValue`` objects. + + """ + + http_options = ( + _BaseCmsMetadataValueServiceRestTransport._BaseListCmsMetadataValues._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_cms_metadata_values( + request, metadata + ) + transcoded_request = _BaseCmsMetadataValueServiceRestTransport._BaseListCmsMetadataValues._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseCmsMetadataValueServiceRestTransport._BaseListCmsMetadataValues._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.CmsMetadataValueServiceClient.ListCmsMetadataValues", + extra={ + "serviceName": "google.ads.admanager.v1.CmsMetadataValueService", + "rpcName": "ListCmsMetadataValues", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = CmsMetadataValueServiceRestTransport._ListCmsMetadataValues._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = cms_metadata_value_service.ListCmsMetadataValuesResponse() + pb_resp = cms_metadata_value_service.ListCmsMetadataValuesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_cms_metadata_values(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_cms_metadata_values_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = cms_metadata_value_service.ListCmsMetadataValuesResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.CmsMetadataValueServiceClient.list_cms_metadata_values", + extra={ + "serviceName": "google.ads.admanager.v1.CmsMetadataValueService", + "rpcName": "ListCmsMetadataValues", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def get_cms_metadata_value( + self, + ) -> Callable[ + [cms_metadata_value_service.GetCmsMetadataValueRequest], + cms_metadata_value_messages.CmsMetadataValue, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetCmsMetadataValue(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_cms_metadata_values( + self, + ) -> Callable[ + [cms_metadata_value_service.ListCmsMetadataValuesRequest], + cms_metadata_value_service.ListCmsMetadataValuesResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListCmsMetadataValues(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseCmsMetadataValueServiceRestTransport._BaseGetOperation, + CmsMetadataValueServiceRestStub, + ): + def __hash__(self): + return hash("CmsMetadataValueServiceRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = ( + _BaseCmsMetadataValueServiceRestTransport._BaseGetOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = _BaseCmsMetadataValueServiceRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseCmsMetadataValueServiceRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.CmsMetadataValueServiceClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.CmsMetadataValueService", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = CmsMetadataValueServiceRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.CmsMetadataValueServiceAsyncClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.CmsMetadataValueService", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("CmsMetadataValueServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/transports/rest_base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/transports/rest_base.py new file mode 100644 index 000000000000..c0f6b83b520d --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/cms_metadata_value_service/transports/rest_base.py @@ -0,0 +1,218 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.ads.admanager_v1.types import ( + cms_metadata_value_messages, + cms_metadata_value_service, +) + +from .base import DEFAULT_CLIENT_INFO, CmsMetadataValueServiceTransport + + +class _BaseCmsMetadataValueServiceRestTransport(CmsMetadataValueServiceTransport): + """Base REST backend transport for CmsMetadataValueService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetCmsMetadataValue: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/cmsMetadataValues/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = cms_metadata_value_service.GetCmsMetadataValueRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseCmsMetadataValueServiceRestTransport._BaseGetCmsMetadataValue._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListCmsMetadataValues: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=networks/*}/cmsMetadataValues", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = cms_metadata_value_service.ListCmsMetadataValuesRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseCmsMetadataValueServiceRestTransport._BaseListCmsMetadataValues._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/operations/reports/runs/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseCmsMetadataValueServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/__init__.py new file mode 100644 index 000000000000..f9976900c61a --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ContactServiceClient + +__all__ = ("ContactServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/client.py new file mode 100644 index 000000000000..a14e82411857 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/client.py @@ -0,0 +1,1547 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +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.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version + +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.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore + +from google.ads.admanager_v1.services.contact_service import pagers +from google.ads.admanager_v1.types import ( + contact_enums, + contact_messages, + contact_service, +) + +from .transports.base import DEFAULT_CLIENT_INFO, ContactServiceTransport +from .transports.rest import ContactServiceRestTransport + + +class ContactServiceClientMeta(type): + """Metaclass for the ContactService 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[ContactServiceTransport]] + _transport_registry["rest"] = ContactServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ContactServiceTransport]: + """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 ContactServiceClient(metaclass=ContactServiceClientMeta): + """Provides methods for handling ``Contact`` objects.""" + + @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 = "admanager.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "admanager.{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: + ContactServiceClient: 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: + ContactServiceClient: 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) -> ContactServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ContactServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def company_path( + network_code: str, + company: str, + ) -> str: + """Returns a fully-qualified company string.""" + return "networks/{network_code}/companies/{company}".format( + network_code=network_code, + company=company, + ) + + @staticmethod + def parse_company_path(path: str) -> Dict[str, str]: + """Parses a company path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/companies/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def contact_path( + network_code: str, + contact: str, + ) -> str: + """Returns a fully-qualified contact string.""" + return "networks/{network_code}/contacts/{contact}".format( + network_code=network_code, + contact=contact, + ) + + @staticmethod + def parse_contact_path(path: str) -> Dict[str, str]: + """Parses a contact path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/contacts/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def network_path( + network_code: str, + ) -> str: + """Returns a fully-qualified network string.""" + return "networks/{network_code}".format( + network_code=network_code, + ) + + @staticmethod + def parse_network_path(path: str) -> Dict[str, str]: + """Parses a network path into its component segments.""" + m = re.match(r"^networks/(?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 = ContactServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ContactServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ContactServiceClient._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 = ContactServiceClient._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, ContactServiceTransport, Callable[..., ContactServiceTransport]] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the contact 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,ContactServiceTransport,Callable[..., ContactServiceTransport]]]): + 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 ContactServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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, + ) = ContactServiceClient._read_environment_variables() + self._client_cert_source = ContactServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = ContactServiceClient._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, ContactServiceTransport) + if transport_provided: + # transport is a ContactServiceTransport 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(ContactServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or ContactServiceClient._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[ContactServiceTransport], Callable[..., ContactServiceTransport] + ] = ( + ContactServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., ContactServiceTransport], 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.admanager_v1.ContactServiceClient`.", + extra={ + "serviceName": "google.ads.admanager.v1.ContactService", + "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.admanager.v1.ContactService", + "credentialsType": None, + }, + ) + + def get_contact( + self, + request: Optional[Union[contact_service.GetContactRequest, dict]] = None, + *, + 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]]] = (), + ) -> contact_messages.Contact: + r"""API to retrieve a ``Contact`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_get_contact(): + # Create a client + client = admanager_v1.ContactServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetContactRequest( + name="name_value", + ) + + # Make the request + response = client.get_contact(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.GetContactRequest, dict]): + The request object. Request object for ``GetContact`` method. + name (str): + Required. The resource name of the Contact. Format: + ``networks/{network_code}/contacts/{contact_id}`` + + This corresponds to the ``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.admanager_v1.types.Contact: + A contact represents a person who is + affiliated with a single company. A + contact can have a variety of contact + information associated to it, and can be + invited to view their company's orders, + line items, creatives, and reports. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, contact_service.GetContactRequest): + request = contact_service.GetContactRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_contact] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_contacts( + self, + request: Optional[Union[contact_service.ListContactsRequest, dict]] = None, + *, + parent: 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.ListContactsPager: + r"""API to retrieve a list of ``Contact`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_list_contacts(): + # Create a client + client = admanager_v1.ContactServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListContactsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_contacts(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.ListContactsRequest, dict]): + The request object. Request object for ``ListContacts`` method. + parent (str): + Required. The parent, which owns this collection of + Contacts. Format: ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.services.contact_service.pagers.ListContactsPager: + Response object for ListContactsRequest containing matching Contact + objects. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, contact_service.ListContactsRequest): + request = contact_service.ListContactsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_contacts] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.ListContactsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def create_contact( + self, + request: Optional[Union[contact_service.CreateContactRequest, dict]] = None, + *, + parent: Optional[str] = None, + contact: Optional[contact_messages.Contact] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> contact_messages.Contact: + r"""API to create a ``Contact`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_create_contact(): + # Create a client + client = admanager_v1.ContactServiceClient() + + # Initialize request argument(s) + request = admanager_v1.CreateContactRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_contact(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.CreateContactRequest, dict]): + The request object. Request object for ``CreateContact`` method. + parent (str): + Required. The parent resource where this ``Contact`` + will be created. Format: ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + contact (google.ads.admanager_v1.types.Contact): + Required. The ``Contact`` to create. + This corresponds to the ``contact`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.Contact: + A contact represents a person who is + affiliated with a single company. A + contact can have a variety of contact + information associated to it, and can be + invited to view their company's orders, + line items, creatives, and reports. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, contact] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, contact_service.CreateContactRequest): + request = contact_service.CreateContactRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if contact is not None: + request.contact = contact + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_contact] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def batch_create_contacts( + self, + request: Optional[ + Union[contact_service.BatchCreateContactsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + requests: Optional[ + MutableSequence[contact_service.CreateContactRequest] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> contact_service.BatchCreateContactsResponse: + r"""API to batch create ``Contact`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_batch_create_contacts(): + # Create a client + client = admanager_v1.ContactServiceClient() + + # Initialize request argument(s) + requests = admanager_v1.CreateContactRequest() + requests.parent = "parent_value" + + request = admanager_v1.BatchCreateContactsRequest( + parent="parent_value", + requests=requests, + ) + + # Make the request + response = client.batch_create_contacts(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.BatchCreateContactsRequest, dict]): + The request object. Request object for ``BatchCreateContacts`` method. + parent (str): + Required. The parent resource where ``Contacts`` will be + created. Format: ``networks/{network_code}`` The parent + field in the CreateContactRequest must match this field. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + requests (MutableSequence[google.ads.admanager_v1.types.CreateContactRequest]): + Required. The ``Contact`` objects to create. A maximum + of 100 objects can be created in a batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.BatchCreateContactsResponse: + Response object for BatchCreateContacts method. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, requests] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, contact_service.BatchCreateContactsRequest): + request = contact_service.BatchCreateContactsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_create_contacts] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe 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_contact( + self, + request: Optional[Union[contact_service.UpdateContactRequest, dict]] = None, + *, + contact: Optional[contact_messages.Contact] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> contact_messages.Contact: + r"""API to update a ``Contact`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_update_contact(): + # Create a client + client = admanager_v1.ContactServiceClient() + + # Initialize request argument(s) + request = admanager_v1.UpdateContactRequest( + ) + + # Make the request + response = client.update_contact(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.UpdateContactRequest, dict]): + The request object. Request object for ``UpdateContact`` method. + contact (google.ads.admanager_v1.types.Contact): + Required. The ``Contact`` to update. + + The ``Contact``'s ``name`` is used to identify the + ``Contact`` to update. + + This corresponds to the ``contact`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Required. The list of fields to + update. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.Contact: + A contact represents a person who is + affiliated with a single company. A + contact can have a variety of contact + information associated to it, and can be + invited to view their company's orders, + line items, creatives, and reports. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [contact, update_mask] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, contact_service.UpdateContactRequest): + request = contact_service.UpdateContactRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if contact is not None: + request.contact = contact + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_contact] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("contact.name", request.contact.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 batch_update_contacts( + self, + request: Optional[ + Union[contact_service.BatchUpdateContactsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + requests: Optional[ + MutableSequence[contact_service.UpdateContactRequest] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> contact_service.BatchUpdateContactsResponse: + r"""API to batch update ``Contact`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_batch_update_contacts(): + # Create a client + client = admanager_v1.ContactServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchUpdateContactsRequest( + parent="parent_value", + ) + + # Make the request + response = client.batch_update_contacts(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.BatchUpdateContactsRequest, dict]): + The request object. Request object for ``BatchUpdateContacts`` method. + parent (str): + Required. The parent resource where ``Contacts`` will be + updated. Format: ``networks/{network_code}`` The parent + field in the UpdateContactRequest must match this field. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + requests (MutableSequence[google.ads.admanager_v1.types.UpdateContactRequest]): + Required. The ``Contact`` objects to update. A maximum + of 100 objects can be updated in a batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.BatchUpdateContactsResponse: + Response object for BatchUpdateContacts method. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, requests] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, contact_service.BatchUpdateContactsRequest): + request = contact_service.BatchUpdateContactsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_update_contacts] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe 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) -> "ContactServiceClient": + 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() + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("ContactServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/pagers.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/pagers.py new file mode 100644 index 000000000000..900bdb93c0b5 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/pagers.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +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 + +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.admanager_v1.types import contact_messages, contact_service + + +class ListContactsPager: + """A pager for iterating through ``list_contacts`` requests. + + This class thinly wraps an initial + :class:`google.ads.admanager_v1.types.ListContactsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``contacts`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListContacts`` requests and continue to iterate + through the ``contacts`` field on the + corresponding responses. + + All the usual :class:`google.ads.admanager_v1.types.ListContactsResponse` + 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[..., contact_service.ListContactsResponse], + request: contact_service.ListContactsRequest, + response: contact_service.ListContactsResponse, + *, + 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.admanager_v1.types.ListContactsRequest): + The initial request object. + response (google.ads.admanager_v1.types.ListContactsResponse): + 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 = contact_service.ListContactsRequest(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[contact_service.ListContactsResponse]: + 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[contact_messages.Contact]: + for page in self.pages: + yield from page.contacts + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/transports/README.rst b/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/transports/README.rst new file mode 100644 index 000000000000..c419382d086e --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`ContactServiceTransport` is the ABC for all transports. +- public child `ContactServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `ContactServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseContactServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `ContactServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/transports/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/transports/__init__.py new file mode 100644 index 000000000000..d5f557899816 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/transports/__init__.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 typing import Dict, Type + +from .base import ContactServiceTransport +from .rest import ContactServiceRestInterceptor, ContactServiceRestTransport + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ContactServiceTransport]] +_transport_registry["rest"] = ContactServiceRestTransport + +__all__ = ( + "ContactServiceTransport", + "ContactServiceRestTransport", + "ContactServiceRestInterceptor", +) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/transports/base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/transports/base.py new file mode 100644 index 000000000000..940e657b0bd1 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/transports/base.py @@ -0,0 +1,260 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version +from google.ads.admanager_v1.types import contact_messages, contact_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 ContactServiceTransport(abc.ABC): + """Abstract transport class for ContactService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/admanager",) + + DEFAULT_HOST: str = "admanager.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: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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_contact: gapic_v1.method.wrap_method( + self.get_contact, + default_timeout=None, + client_info=client_info, + ), + self.list_contacts: gapic_v1.method.wrap_method( + self.list_contacts, + default_timeout=None, + client_info=client_info, + ), + self.create_contact: gapic_v1.method.wrap_method( + self.create_contact, + default_timeout=None, + client_info=client_info, + ), + self.batch_create_contacts: gapic_v1.method.wrap_method( + self.batch_create_contacts, + default_timeout=None, + client_info=client_info, + ), + self.update_contact: gapic_v1.method.wrap_method( + self.update_contact, + default_timeout=None, + client_info=client_info, + ), + self.batch_update_contacts: gapic_v1.method.wrap_method( + self.batch_update_contacts, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + 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_contact( + self, + ) -> Callable[ + [contact_service.GetContactRequest], + Union[contact_messages.Contact, Awaitable[contact_messages.Contact]], + ]: + raise NotImplementedError() + + @property + def list_contacts( + self, + ) -> Callable[ + [contact_service.ListContactsRequest], + Union[ + contact_service.ListContactsResponse, + Awaitable[contact_service.ListContactsResponse], + ], + ]: + raise NotImplementedError() + + @property + def create_contact( + self, + ) -> Callable[ + [contact_service.CreateContactRequest], + Union[contact_messages.Contact, Awaitable[contact_messages.Contact]], + ]: + raise NotImplementedError() + + @property + def batch_create_contacts( + self, + ) -> Callable[ + [contact_service.BatchCreateContactsRequest], + Union[ + contact_service.BatchCreateContactsResponse, + Awaitable[contact_service.BatchCreateContactsResponse], + ], + ]: + raise NotImplementedError() + + @property + def update_contact( + self, + ) -> Callable[ + [contact_service.UpdateContactRequest], + Union[contact_messages.Contact, Awaitable[contact_messages.Contact]], + ]: + raise NotImplementedError() + + @property + def batch_update_contacts( + self, + ) -> Callable[ + [contact_service.BatchUpdateContactsRequest], + Union[ + contact_service.BatchUpdateContactsResponse, + Awaitable[contact_service.BatchUpdateContactsResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ContactServiceTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/transports/rest.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/transports/rest.py new file mode 100644 index 000000000000..8ea86924104b --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/transports/rest.py @@ -0,0 +1,1667 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.ads.admanager_v1.types import contact_messages, contact_service + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseContactServiceRestTransport + +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 = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class ContactServiceRestInterceptor: + """Interceptor for ContactService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the ContactServiceRestTransport. + + .. code-block:: python + class MyCustomContactServiceInterceptor(ContactServiceRestInterceptor): + def pre_batch_create_contacts(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_create_contacts(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_update_contacts(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_update_contacts(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_contact(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_contact(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_contact(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_contact(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_contacts(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_contacts(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_contact(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_contact(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ContactServiceRestTransport(interceptor=MyCustomContactServiceInterceptor()) + client = ContactServiceClient(transport=transport) + + + """ + + def pre_batch_create_contacts( + self, + request: contact_service.BatchCreateContactsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + contact_service.BatchCreateContactsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for batch_create_contacts + + Override in a subclass to manipulate the request or metadata + before they are sent to the ContactService server. + """ + return request, metadata + + def post_batch_create_contacts( + self, response: contact_service.BatchCreateContactsResponse + ) -> contact_service.BatchCreateContactsResponse: + """Post-rpc interceptor for batch_create_contacts + + DEPRECATED. Please use the `post_batch_create_contacts_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the ContactService server but before + it is returned to user code. This `post_batch_create_contacts` interceptor runs + before the `post_batch_create_contacts_with_metadata` interceptor. + """ + return response + + def post_batch_create_contacts_with_metadata( + self, + response: contact_service.BatchCreateContactsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + contact_service.BatchCreateContactsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for batch_create_contacts + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ContactService server but before it is returned to user code. + + We recommend only using this `post_batch_create_contacts_with_metadata` + interceptor in new development instead of the `post_batch_create_contacts` interceptor. + When both interceptors are used, this `post_batch_create_contacts_with_metadata` interceptor runs after the + `post_batch_create_contacts` interceptor. The (possibly modified) response returned by + `post_batch_create_contacts` will be passed to + `post_batch_create_contacts_with_metadata`. + """ + return response, metadata + + def pre_batch_update_contacts( + self, + request: contact_service.BatchUpdateContactsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + contact_service.BatchUpdateContactsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for batch_update_contacts + + Override in a subclass to manipulate the request or metadata + before they are sent to the ContactService server. + """ + return request, metadata + + def post_batch_update_contacts( + self, response: contact_service.BatchUpdateContactsResponse + ) -> contact_service.BatchUpdateContactsResponse: + """Post-rpc interceptor for batch_update_contacts + + DEPRECATED. Please use the `post_batch_update_contacts_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the ContactService server but before + it is returned to user code. This `post_batch_update_contacts` interceptor runs + before the `post_batch_update_contacts_with_metadata` interceptor. + """ + return response + + def post_batch_update_contacts_with_metadata( + self, + response: contact_service.BatchUpdateContactsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + contact_service.BatchUpdateContactsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for batch_update_contacts + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ContactService server but before it is returned to user code. + + We recommend only using this `post_batch_update_contacts_with_metadata` + interceptor in new development instead of the `post_batch_update_contacts` interceptor. + When both interceptors are used, this `post_batch_update_contacts_with_metadata` interceptor runs after the + `post_batch_update_contacts` interceptor. The (possibly modified) response returned by + `post_batch_update_contacts` will be passed to + `post_batch_update_contacts_with_metadata`. + """ + return response, metadata + + def pre_create_contact( + self, + request: contact_service.CreateContactRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + contact_service.CreateContactRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for create_contact + + Override in a subclass to manipulate the request or metadata + before they are sent to the ContactService server. + """ + return request, metadata + + def post_create_contact( + self, response: contact_messages.Contact + ) -> contact_messages.Contact: + """Post-rpc interceptor for create_contact + + DEPRECATED. Please use the `post_create_contact_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the ContactService server but before + it is returned to user code. This `post_create_contact` interceptor runs + before the `post_create_contact_with_metadata` interceptor. + """ + return response + + def post_create_contact_with_metadata( + self, + response: contact_messages.Contact, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[contact_messages.Contact, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_contact + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ContactService server but before it is returned to user code. + + We recommend only using this `post_create_contact_with_metadata` + interceptor in new development instead of the `post_create_contact` interceptor. + When both interceptors are used, this `post_create_contact_with_metadata` interceptor runs after the + `post_create_contact` interceptor. The (possibly modified) response returned by + `post_create_contact` will be passed to + `post_create_contact_with_metadata`. + """ + return response, metadata + + def pre_get_contact( + self, + request: contact_service.GetContactRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + contact_service.GetContactRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_contact + + Override in a subclass to manipulate the request or metadata + before they are sent to the ContactService server. + """ + return request, metadata + + def post_get_contact( + self, response: contact_messages.Contact + ) -> contact_messages.Contact: + """Post-rpc interceptor for get_contact + + DEPRECATED. Please use the `post_get_contact_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the ContactService server but before + it is returned to user code. This `post_get_contact` interceptor runs + before the `post_get_contact_with_metadata` interceptor. + """ + return response + + def post_get_contact_with_metadata( + self, + response: contact_messages.Contact, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[contact_messages.Contact, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_contact + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ContactService server but before it is returned to user code. + + We recommend only using this `post_get_contact_with_metadata` + interceptor in new development instead of the `post_get_contact` interceptor. + When both interceptors are used, this `post_get_contact_with_metadata` interceptor runs after the + `post_get_contact` interceptor. The (possibly modified) response returned by + `post_get_contact` will be passed to + `post_get_contact_with_metadata`. + """ + return response, metadata + + def pre_list_contacts( + self, + request: contact_service.ListContactsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + contact_service.ListContactsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for list_contacts + + Override in a subclass to manipulate the request or metadata + before they are sent to the ContactService server. + """ + return request, metadata + + def post_list_contacts( + self, response: contact_service.ListContactsResponse + ) -> contact_service.ListContactsResponse: + """Post-rpc interceptor for list_contacts + + DEPRECATED. Please use the `post_list_contacts_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the ContactService server but before + it is returned to user code. This `post_list_contacts` interceptor runs + before the `post_list_contacts_with_metadata` interceptor. + """ + return response + + def post_list_contacts_with_metadata( + self, + response: contact_service.ListContactsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + contact_service.ListContactsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_contacts + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ContactService server but before it is returned to user code. + + We recommend only using this `post_list_contacts_with_metadata` + interceptor in new development instead of the `post_list_contacts` interceptor. + When both interceptors are used, this `post_list_contacts_with_metadata` interceptor runs after the + `post_list_contacts` interceptor. The (possibly modified) response returned by + `post_list_contacts` will be passed to + `post_list_contacts_with_metadata`. + """ + return response, metadata + + def pre_update_contact( + self, + request: contact_service.UpdateContactRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + contact_service.UpdateContactRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for update_contact + + Override in a subclass to manipulate the request or metadata + before they are sent to the ContactService server. + """ + return request, metadata + + def post_update_contact( + self, response: contact_messages.Contact + ) -> contact_messages.Contact: + """Post-rpc interceptor for update_contact + + DEPRECATED. Please use the `post_update_contact_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the ContactService server but before + it is returned to user code. This `post_update_contact` interceptor runs + before the `post_update_contact_with_metadata` interceptor. + """ + return response + + def post_update_contact_with_metadata( + self, + response: contact_messages.Contact, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[contact_messages.Contact, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_contact + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ContactService server but before it is returned to user code. + + We recommend only using this `post_update_contact_with_metadata` + interceptor in new development instead of the `post_update_contact` interceptor. + When both interceptors are used, this `post_update_contact_with_metadata` interceptor runs after the + `post_update_contact` interceptor. The (possibly modified) response returned by + `post_update_contact` will be passed to + `post_update_contact_with_metadata`. + """ + return response, metadata + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the ContactService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the ContactService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ContactServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ContactServiceRestInterceptor + + +class ContactServiceRestTransport(_BaseContactServiceRestTransport): + """REST backend synchronous transport for ContactService. + + Provides methods for handling ``Contact`` objects. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[ContactServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or ContactServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _BatchCreateContacts( + _BaseContactServiceRestTransport._BaseBatchCreateContacts, + ContactServiceRestStub, + ): + def __hash__(self): + return hash("ContactServiceRestTransport.BatchCreateContacts") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: contact_service.BatchCreateContactsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> contact_service.BatchCreateContactsResponse: + r"""Call the batch create contacts method over HTTP. + + Args: + request (~.contact_service.BatchCreateContactsRequest): + The request object. Request object for ``BatchCreateContacts`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.contact_service.BatchCreateContactsResponse: + Response object for ``BatchCreateContacts`` method. + """ + + http_options = ( + _BaseContactServiceRestTransport._BaseBatchCreateContacts._get_http_options() + ) + + request, metadata = self._interceptor.pre_batch_create_contacts( + request, metadata + ) + transcoded_request = _BaseContactServiceRestTransport._BaseBatchCreateContacts._get_transcoded_request( + http_options, request + ) + + body = _BaseContactServiceRestTransport._BaseBatchCreateContacts._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseContactServiceRestTransport._BaseBatchCreateContacts._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.ContactServiceClient.BatchCreateContacts", + extra={ + "serviceName": "google.ads.admanager.v1.ContactService", + "rpcName": "BatchCreateContacts", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ContactServiceRestTransport._BatchCreateContacts._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = contact_service.BatchCreateContactsResponse() + pb_resp = contact_service.BatchCreateContactsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_create_contacts(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_create_contacts_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + contact_service.BatchCreateContactsResponse.to_json(response) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.ContactServiceClient.batch_create_contacts", + extra={ + "serviceName": "google.ads.admanager.v1.ContactService", + "rpcName": "BatchCreateContacts", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _BatchUpdateContacts( + _BaseContactServiceRestTransport._BaseBatchUpdateContacts, + ContactServiceRestStub, + ): + def __hash__(self): + return hash("ContactServiceRestTransport.BatchUpdateContacts") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: contact_service.BatchUpdateContactsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> contact_service.BatchUpdateContactsResponse: + r"""Call the batch update contacts method over HTTP. + + Args: + request (~.contact_service.BatchUpdateContactsRequest): + The request object. Request object for ``BatchUpdateContacts`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.contact_service.BatchUpdateContactsResponse: + Response object for ``BatchUpdateContacts`` method. + """ + + http_options = ( + _BaseContactServiceRestTransport._BaseBatchUpdateContacts._get_http_options() + ) + + request, metadata = self._interceptor.pre_batch_update_contacts( + request, metadata + ) + transcoded_request = _BaseContactServiceRestTransport._BaseBatchUpdateContacts._get_transcoded_request( + http_options, request + ) + + body = _BaseContactServiceRestTransport._BaseBatchUpdateContacts._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseContactServiceRestTransport._BaseBatchUpdateContacts._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.ContactServiceClient.BatchUpdateContacts", + extra={ + "serviceName": "google.ads.admanager.v1.ContactService", + "rpcName": "BatchUpdateContacts", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ContactServiceRestTransport._BatchUpdateContacts._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = contact_service.BatchUpdateContactsResponse() + pb_resp = contact_service.BatchUpdateContactsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_update_contacts(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_update_contacts_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + contact_service.BatchUpdateContactsResponse.to_json(response) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.ContactServiceClient.batch_update_contacts", + extra={ + "serviceName": "google.ads.admanager.v1.ContactService", + "rpcName": "BatchUpdateContacts", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _CreateContact( + _BaseContactServiceRestTransport._BaseCreateContact, ContactServiceRestStub + ): + def __hash__(self): + return hash("ContactServiceRestTransport.CreateContact") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: contact_service.CreateContactRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> contact_messages.Contact: + r"""Call the create contact method over HTTP. + + Args: + request (~.contact_service.CreateContactRequest): + The request object. Request object for ``CreateContact`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.contact_messages.Contact: + A contact represents a person who is + affiliated with a single company. A + contact can have a variety of contact + information associated to it, and can be + invited to view their company's orders, + line items, creatives, and reports. + + """ + + http_options = ( + _BaseContactServiceRestTransport._BaseCreateContact._get_http_options() + ) + + request, metadata = self._interceptor.pre_create_contact(request, metadata) + transcoded_request = _BaseContactServiceRestTransport._BaseCreateContact._get_transcoded_request( + http_options, request + ) + + body = _BaseContactServiceRestTransport._BaseCreateContact._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseContactServiceRestTransport._BaseCreateContact._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.ContactServiceClient.CreateContact", + extra={ + "serviceName": "google.ads.admanager.v1.ContactService", + "rpcName": "CreateContact", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ContactServiceRestTransport._CreateContact._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = contact_messages.Contact() + pb_resp = contact_messages.Contact.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_contact(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_contact_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = contact_messages.Contact.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.ContactServiceClient.create_contact", + extra={ + "serviceName": "google.ads.admanager.v1.ContactService", + "rpcName": "CreateContact", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _GetContact( + _BaseContactServiceRestTransport._BaseGetContact, ContactServiceRestStub + ): + def __hash__(self): + return hash("ContactServiceRestTransport.GetContact") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: contact_service.GetContactRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> contact_messages.Contact: + r"""Call the get contact method over HTTP. + + Args: + request (~.contact_service.GetContactRequest): + The request object. Request object for ``GetContact`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.contact_messages.Contact: + A contact represents a person who is + affiliated with a single company. A + contact can have a variety of contact + information associated to it, and can be + invited to view their company's orders, + line items, creatives, and reports. + + """ + + http_options = ( + _BaseContactServiceRestTransport._BaseGetContact._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_contact(request, metadata) + transcoded_request = _BaseContactServiceRestTransport._BaseGetContact._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = ( + _BaseContactServiceRestTransport._BaseGetContact._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.ContactServiceClient.GetContact", + extra={ + "serviceName": "google.ads.admanager.v1.ContactService", + "rpcName": "GetContact", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ContactServiceRestTransport._GetContact._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = contact_messages.Contact() + pb_resp = contact_messages.Contact.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_contact(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_contact_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = contact_messages.Contact.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.ContactServiceClient.get_contact", + extra={ + "serviceName": "google.ads.admanager.v1.ContactService", + "rpcName": "GetContact", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListContacts( + _BaseContactServiceRestTransport._BaseListContacts, ContactServiceRestStub + ): + def __hash__(self): + return hash("ContactServiceRestTransport.ListContacts") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: contact_service.ListContactsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> contact_service.ListContactsResponse: + r"""Call the list contacts method over HTTP. + + Args: + request (~.contact_service.ListContactsRequest): + The request object. Request object for ``ListContacts`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.contact_service.ListContactsResponse: + Response object for ``ListContactsRequest`` containing + matching ``Contact`` objects. + + """ + + http_options = ( + _BaseContactServiceRestTransport._BaseListContacts._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_contacts(request, metadata) + transcoded_request = _BaseContactServiceRestTransport._BaseListContacts._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseContactServiceRestTransport._BaseListContacts._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.ContactServiceClient.ListContacts", + extra={ + "serviceName": "google.ads.admanager.v1.ContactService", + "rpcName": "ListContacts", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ContactServiceRestTransport._ListContacts._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = contact_service.ListContactsResponse() + pb_resp = contact_service.ListContactsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_contacts(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_contacts_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = contact_service.ListContactsResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.ContactServiceClient.list_contacts", + extra={ + "serviceName": "google.ads.admanager.v1.ContactService", + "rpcName": "ListContacts", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _UpdateContact( + _BaseContactServiceRestTransport._BaseUpdateContact, ContactServiceRestStub + ): + def __hash__(self): + return hash("ContactServiceRestTransport.UpdateContact") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: contact_service.UpdateContactRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> contact_messages.Contact: + r"""Call the update contact method over HTTP. + + Args: + request (~.contact_service.UpdateContactRequest): + The request object. Request object for ``UpdateContact`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.contact_messages.Contact: + A contact represents a person who is + affiliated with a single company. A + contact can have a variety of contact + information associated to it, and can be + invited to view their company's orders, + line items, creatives, and reports. + + """ + + http_options = ( + _BaseContactServiceRestTransport._BaseUpdateContact._get_http_options() + ) + + request, metadata = self._interceptor.pre_update_contact(request, metadata) + transcoded_request = _BaseContactServiceRestTransport._BaseUpdateContact._get_transcoded_request( + http_options, request + ) + + body = _BaseContactServiceRestTransport._BaseUpdateContact._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseContactServiceRestTransport._BaseUpdateContact._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.ContactServiceClient.UpdateContact", + extra={ + "serviceName": "google.ads.admanager.v1.ContactService", + "rpcName": "UpdateContact", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ContactServiceRestTransport._UpdateContact._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = contact_messages.Contact() + pb_resp = contact_messages.Contact.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_update_contact(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_contact_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = contact_messages.Contact.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.ContactServiceClient.update_contact", + extra={ + "serviceName": "google.ads.admanager.v1.ContactService", + "rpcName": "UpdateContact", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def batch_create_contacts( + self, + ) -> Callable[ + [contact_service.BatchCreateContactsRequest], + contact_service.BatchCreateContactsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchCreateContacts(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_update_contacts( + self, + ) -> Callable[ + [contact_service.BatchUpdateContactsRequest], + contact_service.BatchUpdateContactsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchUpdateContacts(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_contact( + self, + ) -> Callable[[contact_service.CreateContactRequest], contact_messages.Contact]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateContact(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_contact( + self, + ) -> Callable[[contact_service.GetContactRequest], contact_messages.Contact]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetContact(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_contacts( + self, + ) -> Callable[ + [contact_service.ListContactsRequest], contact_service.ListContactsResponse + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListContacts(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_contact( + self, + ) -> Callable[[contact_service.UpdateContactRequest], contact_messages.Contact]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateContact(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseContactServiceRestTransport._BaseGetOperation, ContactServiceRestStub + ): + def __hash__(self): + return hash("ContactServiceRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = ( + _BaseContactServiceRestTransport._BaseGetOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = _BaseContactServiceRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseContactServiceRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.ContactServiceClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.ContactService", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ContactServiceRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.ContactServiceAsyncClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.ContactService", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("ContactServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/transports/rest_base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/transports/rest_base.py new file mode 100644 index 000000000000..9f705472d629 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/contact_service/transports/rest_base.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 json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.ads.admanager_v1.types import contact_messages, contact_service + +from .base import DEFAULT_CLIENT_INFO, ContactServiceTransport + + +class _BaseContactServiceRestTransport(ContactServiceTransport): + """Base REST backend transport for ContactService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseBatchCreateContacts: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/contacts:batchCreate", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = contact_service.BatchCreateContactsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseContactServiceRestTransport._BaseBatchCreateContacts._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseBatchUpdateContacts: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/contacts:batchUpdate", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = contact_service.BatchUpdateContactsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseContactServiceRestTransport._BaseBatchUpdateContacts._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseCreateContact: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/contacts", + "body": "contact", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = contact_service.CreateContactRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseContactServiceRestTransport._BaseCreateContact._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetContact: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/contacts/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = contact_service.GetContactRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseContactServiceRestTransport._BaseGetContact._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListContacts: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=networks/*}/contacts", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = contact_service.ListContactsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseContactServiceRestTransport._BaseListContacts._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateContact: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "updateMask": {}, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v1/{contact.name=networks/*/contacts/*}", + "body": "contact", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = contact_service.UpdateContactRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseContactServiceRestTransport._BaseUpdateContact._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/operations/reports/runs/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseContactServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/__init__.py new file mode 100644 index 000000000000..93b19fcb4842 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ContentBundleServiceClient + +__all__ = ("ContentBundleServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/client.py new file mode 100644 index 000000000000..fb1239c6fe0a --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_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 ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +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.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version + +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.longrunning import operations_pb2 # type: ignore + +from google.ads.admanager_v1.services.content_bundle_service import pagers +from google.ads.admanager_v1.types import ( + content_bundle_messages, + content_bundle_service, +) + +from .transports.base import DEFAULT_CLIENT_INFO, ContentBundleServiceTransport +from .transports.rest import ContentBundleServiceRestTransport + + +class ContentBundleServiceClientMeta(type): + """Metaclass for the ContentBundleService 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[ContentBundleServiceTransport]] + _transport_registry["rest"] = ContentBundleServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ContentBundleServiceTransport]: + """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 ContentBundleServiceClient(metaclass=ContentBundleServiceClientMeta): + """Provides methods for handling ``ContentBundle`` objects.""" + + @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 = "admanager.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "admanager.{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: + ContentBundleServiceClient: 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: + ContentBundleServiceClient: 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) -> ContentBundleServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ContentBundleServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def content_bundle_path( + network_code: str, + content_bundle: str, + ) -> str: + """Returns a fully-qualified content_bundle string.""" + return "networks/{network_code}/contentBundles/{content_bundle}".format( + network_code=network_code, + content_bundle=content_bundle, + ) + + @staticmethod + def parse_content_bundle_path(path: str) -> Dict[str, str]: + """Parses a content_bundle path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/contentBundles/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def network_path( + network_code: str, + ) -> str: + """Returns a fully-qualified network string.""" + return "networks/{network_code}".format( + network_code=network_code, + ) + + @staticmethod + def parse_network_path(path: str) -> Dict[str, str]: + """Parses a network path into its component segments.""" + m = re.match(r"^networks/(?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 = ContentBundleServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ContentBundleServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ContentBundleServiceClient._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 = ContentBundleServiceClient._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, + ContentBundleServiceTransport, + Callable[..., ContentBundleServiceTransport], + ] + ] = 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 bundle 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,ContentBundleServiceTransport,Callable[..., ContentBundleServiceTransport]]]): + 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 ContentBundleServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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, + ) = ContentBundleServiceClient._read_environment_variables() + self._client_cert_source = ContentBundleServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = ContentBundleServiceClient._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, ContentBundleServiceTransport) + if transport_provided: + # transport is a ContentBundleServiceTransport 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(ContentBundleServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or ContentBundleServiceClient._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[ContentBundleServiceTransport], + Callable[..., ContentBundleServiceTransport], + ] = ( + ContentBundleServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., ContentBundleServiceTransport], 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.admanager_v1.ContentBundleServiceClient`.", + extra={ + "serviceName": "google.ads.admanager.v1.ContentBundleService", + "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.admanager.v1.ContentBundleService", + "credentialsType": None, + }, + ) + + def get_content_bundle( + self, + request: Optional[ + Union[content_bundle_service.GetContentBundleRequest, dict] + ] = None, + *, + 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]]] = (), + ) -> content_bundle_messages.ContentBundle: + r"""API to retrieve a ``ContentBundle`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_get_content_bundle(): + # Create a client + client = admanager_v1.ContentBundleServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetContentBundleRequest( + name="name_value", + ) + + # Make the request + response = client.get_content_bundle(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.GetContentBundleRequest, dict]): + The request object. Request object for ``GetContentBundle`` method. + name (str): + Required. The resource name of the ContentBundle. + Format: + ``networks/{network_code}/contentBundles/{content_bundle_id}`` + + This corresponds to the ``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.admanager_v1.types.ContentBundle: + A [ContentBundle][google.ads.admanager.v1.ContentBundle] is a grouping of + individual + [Content][google.ads.admanager.v1.Content]. A + [ContentBundle][google.ads.admanager.v1.ContentBundle] + is defined as including the + [Content][google.ads.admanager.v1.Content] that match + certain filter rules along with the option to + explicitly include or exclude certain Content IDs. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, content_bundle_service.GetContentBundleRequest): + request = content_bundle_service.GetContentBundleRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_content_bundle] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_content_bundles( + self, + request: Optional[ + Union[content_bundle_service.ListContentBundlesRequest, dict] + ] = None, + *, + parent: 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.ListContentBundlesPager: + r"""API to retrieve a list of ``ContentBundle`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_list_content_bundles(): + # Create a client + client = admanager_v1.ContentBundleServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListContentBundlesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_content_bundles(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.ListContentBundlesRequest, dict]): + The request object. Request object for ``ListContentBundles`` method. + parent (str): + Required. The parent, which owns this collection of + ContentBundles. Format: ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.services.content_bundle_service.pagers.ListContentBundlesPager: + Response object for ListContentBundlesRequest containing matching + ContentBundle objects. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request 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_bundle_service.ListContentBundlesRequest): + request = content_bundle_service.ListContentBundlesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_content_bundles] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.ListContentBundlesPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ContentBundleServiceClient": + 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() + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("ContentBundleServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/pagers.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/pagers.py new file mode 100644 index 000000000000..c010507bcda3 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/pagers.py @@ -0,0 +1,120 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +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 + +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.admanager_v1.types import ( + content_bundle_messages, + content_bundle_service, +) + + +class ListContentBundlesPager: + """A pager for iterating through ``list_content_bundles`` requests. + + This class thinly wraps an initial + :class:`google.ads.admanager_v1.types.ListContentBundlesResponse` object, and + provides an ``__iter__`` method to iterate through its + ``content_bundles`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListContentBundles`` requests and continue to iterate + through the ``content_bundles`` field on the + corresponding responses. + + All the usual :class:`google.ads.admanager_v1.types.ListContentBundlesResponse` + 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[..., content_bundle_service.ListContentBundlesResponse], + request: content_bundle_service.ListContentBundlesRequest, + response: content_bundle_service.ListContentBundlesResponse, + *, + 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.admanager_v1.types.ListContentBundlesRequest): + The initial request object. + response (google.ads.admanager_v1.types.ListContentBundlesResponse): + 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 = content_bundle_service.ListContentBundlesRequest(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[content_bundle_service.ListContentBundlesResponse]: + 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[content_bundle_messages.ContentBundle]: + for page in self.pages: + yield from page.content_bundles + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/transports/README.rst b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/transports/README.rst new file mode 100644 index 000000000000..1b814a9be9b5 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`ContentBundleServiceTransport` is the ABC for all transports. +- public child `ContentBundleServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `ContentBundleServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseContentBundleServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `ContentBundleServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/transports/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/transports/__init__.py new file mode 100644 index 000000000000..435b5c1001f5 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/transports/__init__.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 typing import Dict, Type + +from .base import ContentBundleServiceTransport +from .rest import ContentBundleServiceRestInterceptor, ContentBundleServiceRestTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[ContentBundleServiceTransport]] +_transport_registry["rest"] = ContentBundleServiceRestTransport + +__all__ = ( + "ContentBundleServiceTransport", + "ContentBundleServiceRestTransport", + "ContentBundleServiceRestInterceptor", +) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/transports/base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/transports/base.py new file mode 100644 index 000000000000..de764d098757 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/transports/base.py @@ -0,0 +1,204 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version +from google.ads.admanager_v1.types import ( + content_bundle_messages, + content_bundle_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 ContentBundleServiceTransport(abc.ABC): + """Abstract transport class for ContentBundleService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/admanager",) + + DEFAULT_HOST: str = "admanager.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: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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_content_bundle: gapic_v1.method.wrap_method( + self.get_content_bundle, + default_timeout=None, + client_info=client_info, + ), + self.list_content_bundles: gapic_v1.method.wrap_method( + self.list_content_bundles, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + 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_content_bundle( + self, + ) -> Callable[ + [content_bundle_service.GetContentBundleRequest], + Union[ + content_bundle_messages.ContentBundle, + Awaitable[content_bundle_messages.ContentBundle], + ], + ]: + raise NotImplementedError() + + @property + def list_content_bundles( + self, + ) -> Callable[ + [content_bundle_service.ListContentBundlesRequest], + Union[ + content_bundle_service.ListContentBundlesResponse, + Awaitable[content_bundle_service.ListContentBundlesResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ContentBundleServiceTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/transports/rest.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/transports/rest.py new file mode 100644 index 000000000000..05cfaf157cbe --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/transports/rest.py @@ -0,0 +1,802 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.ads.admanager_v1.types import ( + content_bundle_messages, + content_bundle_service, +) + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseContentBundleServiceRestTransport + +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 = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class ContentBundleServiceRestInterceptor: + """Interceptor for ContentBundleService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the ContentBundleServiceRestTransport. + + .. code-block:: python + class MyCustomContentBundleServiceInterceptor(ContentBundleServiceRestInterceptor): + def pre_get_content_bundle(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_content_bundle(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_content_bundles(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_content_bundles(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ContentBundleServiceRestTransport(interceptor=MyCustomContentBundleServiceInterceptor()) + client = ContentBundleServiceClient(transport=transport) + + + """ + + def pre_get_content_bundle( + self, + request: content_bundle_service.GetContentBundleRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + content_bundle_service.GetContentBundleRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for get_content_bundle + + Override in a subclass to manipulate the request or metadata + before they are sent to the ContentBundleService server. + """ + return request, metadata + + def post_get_content_bundle( + self, response: content_bundle_messages.ContentBundle + ) -> content_bundle_messages.ContentBundle: + """Post-rpc interceptor for get_content_bundle + + DEPRECATED. Please use the `post_get_content_bundle_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the ContentBundleService server but before + it is returned to user code. This `post_get_content_bundle` interceptor runs + before the `post_get_content_bundle_with_metadata` interceptor. + """ + return response + + def post_get_content_bundle_with_metadata( + self, + response: content_bundle_messages.ContentBundle, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + content_bundle_messages.ContentBundle, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_content_bundle + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ContentBundleService server but before it is returned to user code. + + We recommend only using this `post_get_content_bundle_with_metadata` + interceptor in new development instead of the `post_get_content_bundle` interceptor. + When both interceptors are used, this `post_get_content_bundle_with_metadata` interceptor runs after the + `post_get_content_bundle` interceptor. The (possibly modified) response returned by + `post_get_content_bundle` will be passed to + `post_get_content_bundle_with_metadata`. + """ + return response, metadata + + def pre_list_content_bundles( + self, + request: content_bundle_service.ListContentBundlesRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + content_bundle_service.ListContentBundlesRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for list_content_bundles + + Override in a subclass to manipulate the request or metadata + before they are sent to the ContentBundleService server. + """ + return request, metadata + + def post_list_content_bundles( + self, response: content_bundle_service.ListContentBundlesResponse + ) -> content_bundle_service.ListContentBundlesResponse: + """Post-rpc interceptor for list_content_bundles + + DEPRECATED. Please use the `post_list_content_bundles_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the ContentBundleService server but before + it is returned to user code. This `post_list_content_bundles` interceptor runs + before the `post_list_content_bundles_with_metadata` interceptor. + """ + return response + + def post_list_content_bundles_with_metadata( + self, + response: content_bundle_service.ListContentBundlesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + content_bundle_service.ListContentBundlesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_content_bundles + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ContentBundleService server but before it is returned to user code. + + We recommend only using this `post_list_content_bundles_with_metadata` + interceptor in new development instead of the `post_list_content_bundles` interceptor. + When both interceptors are used, this `post_list_content_bundles_with_metadata` interceptor runs after the + `post_list_content_bundles` interceptor. The (possibly modified) response returned by + `post_list_content_bundles` will be passed to + `post_list_content_bundles_with_metadata`. + """ + return response, metadata + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the ContentBundleService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the ContentBundleService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ContentBundleServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ContentBundleServiceRestInterceptor + + +class ContentBundleServiceRestTransport(_BaseContentBundleServiceRestTransport): + """REST backend synchronous transport for ContentBundleService. + + Provides methods for handling ``ContentBundle`` objects. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[ContentBundleServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or ContentBundleServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _GetContentBundle( + _BaseContentBundleServiceRestTransport._BaseGetContentBundle, + ContentBundleServiceRestStub, + ): + def __hash__(self): + return hash("ContentBundleServiceRestTransport.GetContentBundle") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: content_bundle_service.GetContentBundleRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> content_bundle_messages.ContentBundle: + r"""Call the get content bundle method over HTTP. + + Args: + request (~.content_bundle_service.GetContentBundleRequest): + The request object. Request object for ``GetContentBundle`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.content_bundle_messages.ContentBundle: + A [ContentBundle][google.ads.admanager.v1.ContentBundle] + is a grouping of individual + [Content][google.ads.admanager.v1.Content]. A + [ContentBundle][google.ads.admanager.v1.ContentBundle] + is defined as including the + [Content][google.ads.admanager.v1.Content] that match + certain filter rules along with the option to explicitly + include or exclude certain Content IDs. + + """ + + http_options = ( + _BaseContentBundleServiceRestTransport._BaseGetContentBundle._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_content_bundle( + request, metadata + ) + transcoded_request = _BaseContentBundleServiceRestTransport._BaseGetContentBundle._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseContentBundleServiceRestTransport._BaseGetContentBundle._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.ContentBundleServiceClient.GetContentBundle", + extra={ + "serviceName": "google.ads.admanager.v1.ContentBundleService", + "rpcName": "GetContentBundle", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + ContentBundleServiceRestTransport._GetContentBundle._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = content_bundle_messages.ContentBundle() + pb_resp = content_bundle_messages.ContentBundle.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_content_bundle(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_content_bundle_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = content_bundle_messages.ContentBundle.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.ContentBundleServiceClient.get_content_bundle", + extra={ + "serviceName": "google.ads.admanager.v1.ContentBundleService", + "rpcName": "GetContentBundle", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListContentBundles( + _BaseContentBundleServiceRestTransport._BaseListContentBundles, + ContentBundleServiceRestStub, + ): + def __hash__(self): + return hash("ContentBundleServiceRestTransport.ListContentBundles") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: content_bundle_service.ListContentBundlesRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> content_bundle_service.ListContentBundlesResponse: + r"""Call the list content bundles method over HTTP. + + Args: + request (~.content_bundle_service.ListContentBundlesRequest): + The request object. Request object for ``ListContentBundles`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.content_bundle_service.ListContentBundlesResponse: + Response object for ``ListContentBundlesRequest`` + containing matching ``ContentBundle`` objects. + + """ + + http_options = ( + _BaseContentBundleServiceRestTransport._BaseListContentBundles._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_content_bundles( + request, metadata + ) + transcoded_request = _BaseContentBundleServiceRestTransport._BaseListContentBundles._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseContentBundleServiceRestTransport._BaseListContentBundles._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.ContentBundleServiceClient.ListContentBundles", + extra={ + "serviceName": "google.ads.admanager.v1.ContentBundleService", + "rpcName": "ListContentBundles", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + ContentBundleServiceRestTransport._ListContentBundles._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = content_bundle_service.ListContentBundlesResponse() + pb_resp = content_bundle_service.ListContentBundlesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_content_bundles(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_content_bundles_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + content_bundle_service.ListContentBundlesResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.ContentBundleServiceClient.list_content_bundles", + extra={ + "serviceName": "google.ads.admanager.v1.ContentBundleService", + "rpcName": "ListContentBundles", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def get_content_bundle( + self, + ) -> Callable[ + [content_bundle_service.GetContentBundleRequest], + content_bundle_messages.ContentBundle, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetContentBundle(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_content_bundles( + self, + ) -> Callable[ + [content_bundle_service.ListContentBundlesRequest], + content_bundle_service.ListContentBundlesResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListContentBundles(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseContentBundleServiceRestTransport._BaseGetOperation, + ContentBundleServiceRestStub, + ): + def __hash__(self): + return hash("ContentBundleServiceRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = ( + _BaseContentBundleServiceRestTransport._BaseGetOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = _BaseContentBundleServiceRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseContentBundleServiceRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.ContentBundleServiceClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.ContentBundleService", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ContentBundleServiceRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.ContentBundleServiceAsyncClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.ContentBundleService", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("ContentBundleServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/transports/rest_base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/transports/rest_base.py new file mode 100644 index 000000000000..8845c8e21077 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_bundle_service/transports/rest_base.py @@ -0,0 +1,214 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.ads.admanager_v1.types import ( + content_bundle_messages, + content_bundle_service, +) + +from .base import DEFAULT_CLIENT_INFO, ContentBundleServiceTransport + + +class _BaseContentBundleServiceRestTransport(ContentBundleServiceTransport): + """Base REST backend transport for ContentBundleService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetContentBundle: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/contentBundles/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = content_bundle_service.GetContentBundleRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseContentBundleServiceRestTransport._BaseGetContentBundle._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListContentBundles: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=networks/*}/contentBundles", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = content_bundle_service.ListContentBundlesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseContentBundleServiceRestTransport._BaseListContentBundles._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/operations/reports/runs/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseContentBundleServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/__init__.py new file mode 100644 index 000000000000..d54eaff28090 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ContentLabelServiceClient + +__all__ = ("ContentLabelServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/client.py new file mode 100644 index 000000000000..9cc2dcb712c2 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/client.py @@ -0,0 +1,1040 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +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.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version + +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.longrunning import operations_pb2 # type: ignore + +from google.ads.admanager_v1.services.content_label_service import pagers +from google.ads.admanager_v1.types import content_label_messages, content_label_service + +from .transports.base import DEFAULT_CLIENT_INFO, ContentLabelServiceTransport +from .transports.rest import ContentLabelServiceRestTransport + + +class ContentLabelServiceClientMeta(type): + """Metaclass for the ContentLabelService 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[ContentLabelServiceTransport]] + _transport_registry["rest"] = ContentLabelServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ContentLabelServiceTransport]: + """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 ContentLabelServiceClient(metaclass=ContentLabelServiceClientMeta): + """Provides methods for handling ``ContentLabel`` objects.""" + + @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 = "admanager.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "admanager.{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: + ContentLabelServiceClient: 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: + ContentLabelServiceClient: 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) -> ContentLabelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ContentLabelServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def content_label_path( + network_code: str, + content_label: str, + ) -> str: + """Returns a fully-qualified content_label string.""" + return "networks/{network_code}/contentLabels/{content_label}".format( + network_code=network_code, + content_label=content_label, + ) + + @staticmethod + def parse_content_label_path(path: str) -> Dict[str, str]: + """Parses a content_label path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/contentLabels/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def network_path( + network_code: str, + ) -> str: + """Returns a fully-qualified network string.""" + return "networks/{network_code}".format( + network_code=network_code, + ) + + @staticmethod + def parse_network_path(path: str) -> Dict[str, str]: + """Parses a network path into its component segments.""" + m = re.match(r"^networks/(?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 = ContentLabelServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ContentLabelServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ContentLabelServiceClient._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 = ContentLabelServiceClient._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, + ContentLabelServiceTransport, + Callable[..., ContentLabelServiceTransport], + ] + ] = 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 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,ContentLabelServiceTransport,Callable[..., ContentLabelServiceTransport]]]): + 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 ContentLabelServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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, + ) = ContentLabelServiceClient._read_environment_variables() + self._client_cert_source = ContentLabelServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = ContentLabelServiceClient._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, ContentLabelServiceTransport) + if transport_provided: + # transport is a ContentLabelServiceTransport 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(ContentLabelServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or ContentLabelServiceClient._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[ContentLabelServiceTransport], + Callable[..., ContentLabelServiceTransport], + ] = ( + ContentLabelServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., ContentLabelServiceTransport], 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.admanager_v1.ContentLabelServiceClient`.", + extra={ + "serviceName": "google.ads.admanager.v1.ContentLabelService", + "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.admanager.v1.ContentLabelService", + "credentialsType": None, + }, + ) + + def get_content_label( + self, + request: Optional[ + Union[content_label_service.GetContentLabelRequest, dict] + ] = None, + *, + 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]]] = (), + ) -> content_label_messages.ContentLabel: + r"""API to retrieve a ``ContentLabel`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_get_content_label(): + # Create a client + client = admanager_v1.ContentLabelServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetContentLabelRequest( + name="name_value", + ) + + # Make the request + response = client.get_content_label(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.GetContentLabelRequest, dict]): + The request object. Request object for ``GetContentLabel`` method. + name (str): + Required. The resource name of the ContentLabel. Format: + ``networks/{network_code}/contentLabels/{content_label_id}`` + + This corresponds to the ``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.admanager_v1.types.ContentLabel: + A content label. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, content_label_service.GetContentLabelRequest): + request = content_label_service.GetContentLabelRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_content_label] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_content_labels( + self, + request: Optional[ + Union[content_label_service.ListContentLabelsRequest, dict] + ] = None, + *, + parent: 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.ListContentLabelsPager: + r"""API to retrieve a list of ``ContentLabel`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_list_content_labels(): + # Create a client + client = admanager_v1.ContentLabelServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListContentLabelsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_content_labels(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.ListContentLabelsRequest, dict]): + The request object. Request object for ``ListContentLabels`` method. + parent (str): + Required. The parent, which owns this collection of + ContentLabels. Format: ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.services.content_label_service.pagers.ListContentLabelsPager: + Response object for ListContentLabelsRequest containing matching + ContentLabel objects. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request 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_label_service.ListContentLabelsRequest): + request = content_label_service.ListContentLabelsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_content_labels] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.ListContentLabelsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ContentLabelServiceClient": + 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() + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("ContentLabelServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/pagers.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/pagers.py new file mode 100644 index 000000000000..31f5522bc145 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/pagers.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +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 + +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.admanager_v1.types import content_label_messages, content_label_service + + +class ListContentLabelsPager: + """A pager for iterating through ``list_content_labels`` requests. + + This class thinly wraps an initial + :class:`google.ads.admanager_v1.types.ListContentLabelsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``content_labels`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListContentLabels`` requests and continue to iterate + through the ``content_labels`` field on the + corresponding responses. + + All the usual :class:`google.ads.admanager_v1.types.ListContentLabelsResponse` + 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[..., content_label_service.ListContentLabelsResponse], + request: content_label_service.ListContentLabelsRequest, + response: content_label_service.ListContentLabelsResponse, + *, + 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.admanager_v1.types.ListContentLabelsRequest): + The initial request object. + response (google.ads.admanager_v1.types.ListContentLabelsResponse): + 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 = content_label_service.ListContentLabelsRequest(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[content_label_service.ListContentLabelsResponse]: + 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[content_label_messages.ContentLabel]: + for page in self.pages: + yield from page.content_labels + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/transports/README.rst b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/transports/README.rst new file mode 100644 index 000000000000..4f9d86d0a7e9 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`ContentLabelServiceTransport` is the ABC for all transports. +- public child `ContentLabelServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `ContentLabelServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseContentLabelServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `ContentLabelServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/transports/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/transports/__init__.py new file mode 100644 index 000000000000..b14b83ab13da --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/transports/__init__.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 typing import Dict, Type + +from .base import ContentLabelServiceTransport +from .rest import ContentLabelServiceRestInterceptor, ContentLabelServiceRestTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[ContentLabelServiceTransport]] +_transport_registry["rest"] = ContentLabelServiceRestTransport + +__all__ = ( + "ContentLabelServiceTransport", + "ContentLabelServiceRestTransport", + "ContentLabelServiceRestInterceptor", +) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/transports/base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/transports/base.py new file mode 100644 index 000000000000..4616dbda0960 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/transports/base.py @@ -0,0 +1,201 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version +from google.ads.admanager_v1.types import content_label_messages, content_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 ContentLabelServiceTransport(abc.ABC): + """Abstract transport class for ContentLabelService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/admanager",) + + DEFAULT_HOST: str = "admanager.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: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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_content_label: gapic_v1.method.wrap_method( + self.get_content_label, + default_timeout=None, + client_info=client_info, + ), + self.list_content_labels: gapic_v1.method.wrap_method( + self.list_content_labels, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + 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_content_label( + self, + ) -> Callable[ + [content_label_service.GetContentLabelRequest], + Union[ + content_label_messages.ContentLabel, + Awaitable[content_label_messages.ContentLabel], + ], + ]: + raise NotImplementedError() + + @property + def list_content_labels( + self, + ) -> Callable[ + [content_label_service.ListContentLabelsRequest], + Union[ + content_label_service.ListContentLabelsResponse, + Awaitable[content_label_service.ListContentLabelsResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ContentLabelServiceTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/transports/rest.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/transports/rest.py new file mode 100644 index 000000000000..09ed6137106b --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/transports/rest.py @@ -0,0 +1,789 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.ads.admanager_v1.types import content_label_messages, content_label_service + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseContentLabelServiceRestTransport + +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 = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class ContentLabelServiceRestInterceptor: + """Interceptor for ContentLabelService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the ContentLabelServiceRestTransport. + + .. code-block:: python + class MyCustomContentLabelServiceInterceptor(ContentLabelServiceRestInterceptor): + def pre_get_content_label(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_content_label(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_content_labels(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_content_labels(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ContentLabelServiceRestTransport(interceptor=MyCustomContentLabelServiceInterceptor()) + client = ContentLabelServiceClient(transport=transport) + + + """ + + def pre_get_content_label( + self, + request: content_label_service.GetContentLabelRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + content_label_service.GetContentLabelRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for get_content_label + + Override in a subclass to manipulate the request or metadata + before they are sent to the ContentLabelService server. + """ + return request, metadata + + def post_get_content_label( + self, response: content_label_messages.ContentLabel + ) -> content_label_messages.ContentLabel: + """Post-rpc interceptor for get_content_label + + DEPRECATED. Please use the `post_get_content_label_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the ContentLabelService server but before + it is returned to user code. This `post_get_content_label` interceptor runs + before the `post_get_content_label_with_metadata` interceptor. + """ + return response + + def post_get_content_label_with_metadata( + self, + response: content_label_messages.ContentLabel, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + content_label_messages.ContentLabel, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_content_label + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ContentLabelService server but before it is returned to user code. + + We recommend only using this `post_get_content_label_with_metadata` + interceptor in new development instead of the `post_get_content_label` interceptor. + When both interceptors are used, this `post_get_content_label_with_metadata` interceptor runs after the + `post_get_content_label` interceptor. The (possibly modified) response returned by + `post_get_content_label` will be passed to + `post_get_content_label_with_metadata`. + """ + return response, metadata + + def pre_list_content_labels( + self, + request: content_label_service.ListContentLabelsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + content_label_service.ListContentLabelsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for list_content_labels + + Override in a subclass to manipulate the request or metadata + before they are sent to the ContentLabelService server. + """ + return request, metadata + + def post_list_content_labels( + self, response: content_label_service.ListContentLabelsResponse + ) -> content_label_service.ListContentLabelsResponse: + """Post-rpc interceptor for list_content_labels + + DEPRECATED. Please use the `post_list_content_labels_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the ContentLabelService server but before + it is returned to user code. This `post_list_content_labels` interceptor runs + before the `post_list_content_labels_with_metadata` interceptor. + """ + return response + + def post_list_content_labels_with_metadata( + self, + response: content_label_service.ListContentLabelsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + content_label_service.ListContentLabelsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_content_labels + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ContentLabelService server but before it is returned to user code. + + We recommend only using this `post_list_content_labels_with_metadata` + interceptor in new development instead of the `post_list_content_labels` interceptor. + When both interceptors are used, this `post_list_content_labels_with_metadata` interceptor runs after the + `post_list_content_labels` interceptor. The (possibly modified) response returned by + `post_list_content_labels` will be passed to + `post_list_content_labels_with_metadata`. + """ + return response, metadata + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the ContentLabelService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the ContentLabelService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ContentLabelServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ContentLabelServiceRestInterceptor + + +class ContentLabelServiceRestTransport(_BaseContentLabelServiceRestTransport): + """REST backend synchronous transport for ContentLabelService. + + Provides methods for handling ``ContentLabel`` objects. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[ContentLabelServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or ContentLabelServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _GetContentLabel( + _BaseContentLabelServiceRestTransport._BaseGetContentLabel, + ContentLabelServiceRestStub, + ): + def __hash__(self): + return hash("ContentLabelServiceRestTransport.GetContentLabel") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: content_label_service.GetContentLabelRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> content_label_messages.ContentLabel: + r"""Call the get content label method over HTTP. + + Args: + request (~.content_label_service.GetContentLabelRequest): + The request object. Request object for ``GetContentLabel`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.content_label_messages.ContentLabel: + A content label. + """ + + http_options = ( + _BaseContentLabelServiceRestTransport._BaseGetContentLabel._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_content_label( + request, metadata + ) + transcoded_request = _BaseContentLabelServiceRestTransport._BaseGetContentLabel._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseContentLabelServiceRestTransport._BaseGetContentLabel._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.ContentLabelServiceClient.GetContentLabel", + extra={ + "serviceName": "google.ads.admanager.v1.ContentLabelService", + "rpcName": "GetContentLabel", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ContentLabelServiceRestTransport._GetContentLabel._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = content_label_messages.ContentLabel() + pb_resp = content_label_messages.ContentLabel.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_content_label(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_content_label_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = content_label_messages.ContentLabel.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.ContentLabelServiceClient.get_content_label", + extra={ + "serviceName": "google.ads.admanager.v1.ContentLabelService", + "rpcName": "GetContentLabel", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListContentLabels( + _BaseContentLabelServiceRestTransport._BaseListContentLabels, + ContentLabelServiceRestStub, + ): + def __hash__(self): + return hash("ContentLabelServiceRestTransport.ListContentLabels") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: content_label_service.ListContentLabelsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> content_label_service.ListContentLabelsResponse: + r"""Call the list content labels method over HTTP. + + Args: + request (~.content_label_service.ListContentLabelsRequest): + The request object. Request object for ``ListContentLabels`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.content_label_service.ListContentLabelsResponse: + Response object for ``ListContentLabelsRequest`` + containing matching ``ContentLabel`` objects. + + """ + + http_options = ( + _BaseContentLabelServiceRestTransport._BaseListContentLabels._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_content_labels( + request, metadata + ) + transcoded_request = _BaseContentLabelServiceRestTransport._BaseListContentLabels._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseContentLabelServiceRestTransport._BaseListContentLabels._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.ContentLabelServiceClient.ListContentLabels", + extra={ + "serviceName": "google.ads.admanager.v1.ContentLabelService", + "rpcName": "ListContentLabels", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + ContentLabelServiceRestTransport._ListContentLabels._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = content_label_service.ListContentLabelsResponse() + pb_resp = content_label_service.ListContentLabelsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_content_labels(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_content_labels_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + content_label_service.ListContentLabelsResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.ContentLabelServiceClient.list_content_labels", + extra={ + "serviceName": "google.ads.admanager.v1.ContentLabelService", + "rpcName": "ListContentLabels", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def get_content_label( + self, + ) -> Callable[ + [content_label_service.GetContentLabelRequest], + content_label_messages.ContentLabel, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetContentLabel(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_content_labels( + self, + ) -> Callable[ + [content_label_service.ListContentLabelsRequest], + content_label_service.ListContentLabelsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListContentLabels(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseContentLabelServiceRestTransport._BaseGetOperation, + ContentLabelServiceRestStub, + ): + def __hash__(self): + return hash("ContentLabelServiceRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = ( + _BaseContentLabelServiceRestTransport._BaseGetOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = _BaseContentLabelServiceRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseContentLabelServiceRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.ContentLabelServiceClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.ContentLabelService", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ContentLabelServiceRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.ContentLabelServiceAsyncClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.ContentLabelService", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("ContentLabelServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/transports/rest_base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/transports/rest_base.py new file mode 100644 index 000000000000..1569ca8e6c15 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_label_service/transports/rest_base.py @@ -0,0 +1,211 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.ads.admanager_v1.types import content_label_messages, content_label_service + +from .base import DEFAULT_CLIENT_INFO, ContentLabelServiceTransport + + +class _BaseContentLabelServiceRestTransport(ContentLabelServiceTransport): + """Base REST backend transport for ContentLabelService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetContentLabel: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/contentLabels/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = content_label_service.GetContentLabelRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseContentLabelServiceRestTransport._BaseGetContentLabel._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListContentLabels: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=networks/*}/contentLabels", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = content_label_service.ListContentLabelsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseContentLabelServiceRestTransport._BaseListContentLabels._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/operations/reports/runs/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseContentLabelServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/__init__.py new file mode 100644 index 000000000000..7287c3d08410 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ContentServiceClient + +__all__ = ("ContentServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/client.py new file mode 100644 index 000000000000..9c17eadfb71d --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/client.py @@ -0,0 +1,1030 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +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.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version + +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.longrunning import operations_pb2 # type: ignore + +from google.ads.admanager_v1.services.content_service import pagers +from google.ads.admanager_v1.types import content_messages, content_service + +from .transports.base import DEFAULT_CLIENT_INFO, ContentServiceTransport +from .transports.rest import ContentServiceRestTransport + + +class ContentServiceClientMeta(type): + """Metaclass for the ContentService 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[ContentServiceTransport]] + _transport_registry["rest"] = ContentServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ContentServiceTransport]: + """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 ContentServiceClient(metaclass=ContentServiceClientMeta): + """Provides methods for handling ``Content`` objects.""" + + @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 = "admanager.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "admanager.{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: + ContentServiceClient: 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: + ContentServiceClient: 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) -> ContentServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ContentServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def content_path( + network_code: str, + content: str, + ) -> str: + """Returns a fully-qualified content string.""" + return "networks/{network_code}/content/{content}".format( + network_code=network_code, + content=content, + ) + + @staticmethod + def parse_content_path(path: str) -> Dict[str, str]: + """Parses a content path into its component segments.""" + m = re.match(r"^networks/(?P.+?)/content/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def network_path( + network_code: str, + ) -> str: + """Returns a fully-qualified network string.""" + return "networks/{network_code}".format( + network_code=network_code, + ) + + @staticmethod + def parse_network_path(path: str) -> Dict[str, str]: + """Parses a network path into its component segments.""" + m = re.match(r"^networks/(?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 = ContentServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ContentServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ContentServiceClient._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 = ContentServiceClient._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, ContentServiceTransport, Callable[..., ContentServiceTransport]] + ] = 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 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,ContentServiceTransport,Callable[..., ContentServiceTransport]]]): + 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 ContentServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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, + ) = ContentServiceClient._read_environment_variables() + self._client_cert_source = ContentServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = ContentServiceClient._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, ContentServiceTransport) + if transport_provided: + # transport is a ContentServiceTransport 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(ContentServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or ContentServiceClient._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[ContentServiceTransport], Callable[..., ContentServiceTransport] + ] = ( + ContentServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., ContentServiceTransport], 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.admanager_v1.ContentServiceClient`.", + extra={ + "serviceName": "google.ads.admanager.v1.ContentService", + "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.admanager.v1.ContentService", + "credentialsType": None, + }, + ) + + def get_content( + self, + request: Optional[Union[content_service.GetContentRequest, dict]] = None, + *, + 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]]] = (), + ) -> content_messages.Content: + r"""API to retrieve a ``Content`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_get_content(): + # Create a client + client = admanager_v1.ContentServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetContentRequest( + name="name_value", + ) + + # Make the request + response = client.get_content(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.GetContentRequest, dict]): + The request object. Request object for ``GetContent`` method. + name (str): + Required. The resource name of the Content. Format: + ``networks/{network_code}/content/{content_id}`` + + This corresponds to the ``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.admanager_v1.types.Content: + A piece of content from a Publisher's + CMS. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, content_service.GetContentRequest): + request = content_service.GetContentRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_content] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_content( + self, + request: Optional[Union[content_service.ListContentRequest, dict]] = None, + *, + parent: 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.ListContentPager: + r"""API to retrieve a list of ``Content`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_list_content(): + # Create a client + client = admanager_v1.ContentServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListContentRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_content(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.ListContentRequest, dict]): + The request object. Request object for ``ListContent`` method. + parent (str): + Required. The parent, which owns this collection of + Content. Format: ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.services.content_service.pagers.ListContentPager: + Response object for ListContentRequest containing matching Content + objects. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request 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_service.ListContentRequest): + request = content_service.ListContentRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_content] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.ListContentPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ContentServiceClient": + 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() + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("ContentServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/pagers.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/pagers.py new file mode 100644 index 000000000000..cc1feb6bb787 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/pagers.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +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 + +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.admanager_v1.types import content_messages, content_service + + +class ListContentPager: + """A pager for iterating through ``list_content`` requests. + + This class thinly wraps an initial + :class:`google.ads.admanager_v1.types.ListContentResponse` object, and + provides an ``__iter__`` method to iterate through its + ``content`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListContent`` requests and continue to iterate + through the ``content`` field on the + corresponding responses. + + All the usual :class:`google.ads.admanager_v1.types.ListContentResponse` + 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[..., content_service.ListContentResponse], + request: content_service.ListContentRequest, + response: content_service.ListContentResponse, + *, + 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.admanager_v1.types.ListContentRequest): + The initial request object. + response (google.ads.admanager_v1.types.ListContentResponse): + 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 = content_service.ListContentRequest(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[content_service.ListContentResponse]: + 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[content_messages.Content]: + for page in self.pages: + yield from page.content + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/transports/README.rst b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/transports/README.rst new file mode 100644 index 000000000000..f737919bf8e5 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`ContentServiceTransport` is the ABC for all transports. +- public child `ContentServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `ContentServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseContentServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `ContentServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/transports/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/transports/__init__.py new file mode 100644 index 000000000000..1cc6a496fd19 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/transports/__init__.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 typing import Dict, Type + +from .base import ContentServiceTransport +from .rest import ContentServiceRestInterceptor, ContentServiceRestTransport + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ContentServiceTransport]] +_transport_registry["rest"] = ContentServiceRestTransport + +__all__ = ( + "ContentServiceTransport", + "ContentServiceRestTransport", + "ContentServiceRestInterceptor", +) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/transports/base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/transports/base.py new file mode 100644 index 000000000000..39c7e700469b --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/transports/base.py @@ -0,0 +1,198 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version +from google.ads.admanager_v1.types import content_messages, content_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 ContentServiceTransport(abc.ABC): + """Abstract transport class for ContentService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/admanager",) + + DEFAULT_HOST: str = "admanager.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: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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_content: gapic_v1.method.wrap_method( + self.get_content, + default_timeout=None, + client_info=client_info, + ), + self.list_content: gapic_v1.method.wrap_method( + self.list_content, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + 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_content( + self, + ) -> Callable[ + [content_service.GetContentRequest], + Union[content_messages.Content, Awaitable[content_messages.Content]], + ]: + raise NotImplementedError() + + @property + def list_content( + self, + ) -> Callable[ + [content_service.ListContentRequest], + Union[ + content_service.ListContentResponse, + Awaitable[content_service.ListContentResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ContentServiceTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/transports/rest.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/transports/rest.py new file mode 100644 index 000000000000..8cb123fa350f --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/transports/rest.py @@ -0,0 +1,771 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.ads.admanager_v1.types import content_messages, content_service + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseContentServiceRestTransport + +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 = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class ContentServiceRestInterceptor: + """Interceptor for ContentService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the ContentServiceRestTransport. + + .. code-block:: python + class MyCustomContentServiceInterceptor(ContentServiceRestInterceptor): + def pre_get_content(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_content(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_content(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_content(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ContentServiceRestTransport(interceptor=MyCustomContentServiceInterceptor()) + client = ContentServiceClient(transport=transport) + + + """ + + def pre_get_content( + self, + request: content_service.GetContentRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + content_service.GetContentRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_content + + Override in a subclass to manipulate the request or metadata + before they are sent to the ContentService server. + """ + return request, metadata + + def post_get_content( + self, response: content_messages.Content + ) -> content_messages.Content: + """Post-rpc interceptor for get_content + + DEPRECATED. Please use the `post_get_content_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the ContentService server but before + it is returned to user code. This `post_get_content` interceptor runs + before the `post_get_content_with_metadata` interceptor. + """ + return response + + def post_get_content_with_metadata( + self, + response: content_messages.Content, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[content_messages.Content, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_content + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ContentService server but before it is returned to user code. + + We recommend only using this `post_get_content_with_metadata` + interceptor in new development instead of the `post_get_content` interceptor. + When both interceptors are used, this `post_get_content_with_metadata` interceptor runs after the + `post_get_content` interceptor. The (possibly modified) response returned by + `post_get_content` will be passed to + `post_get_content_with_metadata`. + """ + return response, metadata + + def pre_list_content( + self, + request: content_service.ListContentRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + content_service.ListContentRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for list_content + + Override in a subclass to manipulate the request or metadata + before they are sent to the ContentService server. + """ + return request, metadata + + def post_list_content( + self, response: content_service.ListContentResponse + ) -> content_service.ListContentResponse: + """Post-rpc interceptor for list_content + + DEPRECATED. Please use the `post_list_content_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the ContentService server but before + it is returned to user code. This `post_list_content` interceptor runs + before the `post_list_content_with_metadata` interceptor. + """ + return response + + def post_list_content_with_metadata( + self, + response: content_service.ListContentResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + content_service.ListContentResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_content + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ContentService server but before it is returned to user code. + + We recommend only using this `post_list_content_with_metadata` + interceptor in new development instead of the `post_list_content` interceptor. + When both interceptors are used, this `post_list_content_with_metadata` interceptor runs after the + `post_list_content` interceptor. The (possibly modified) response returned by + `post_list_content` will be passed to + `post_list_content_with_metadata`. + """ + return response, metadata + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the ContentService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the ContentService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ContentServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ContentServiceRestInterceptor + + +class ContentServiceRestTransport(_BaseContentServiceRestTransport): + """REST backend synchronous transport for ContentService. + + Provides methods for handling ``Content`` objects. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[ContentServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or ContentServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _GetContent( + _BaseContentServiceRestTransport._BaseGetContent, ContentServiceRestStub + ): + def __hash__(self): + return hash("ContentServiceRestTransport.GetContent") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: content_service.GetContentRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> content_messages.Content: + r"""Call the get content method over HTTP. + + Args: + request (~.content_service.GetContentRequest): + The request object. Request object for ``GetContent`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.content_messages.Content: + A piece of content from a Publisher's + CMS. + + """ + + http_options = ( + _BaseContentServiceRestTransport._BaseGetContent._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_content(request, metadata) + transcoded_request = _BaseContentServiceRestTransport._BaseGetContent._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = ( + _BaseContentServiceRestTransport._BaseGetContent._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.ContentServiceClient.GetContent", + extra={ + "serviceName": "google.ads.admanager.v1.ContentService", + "rpcName": "GetContent", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ContentServiceRestTransport._GetContent._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = content_messages.Content() + pb_resp = content_messages.Content.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_content(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_content_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = content_messages.Content.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.ContentServiceClient.get_content", + extra={ + "serviceName": "google.ads.admanager.v1.ContentService", + "rpcName": "GetContent", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListContent( + _BaseContentServiceRestTransport._BaseListContent, ContentServiceRestStub + ): + def __hash__(self): + return hash("ContentServiceRestTransport.ListContent") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: content_service.ListContentRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> content_service.ListContentResponse: + r"""Call the list content method over HTTP. + + Args: + request (~.content_service.ListContentRequest): + The request object. Request object for ``ListContent`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.content_service.ListContentResponse: + Response object for ``ListContentRequest`` containing + matching ``Content`` objects. + + """ + + http_options = ( + _BaseContentServiceRestTransport._BaseListContent._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_content(request, metadata) + transcoded_request = _BaseContentServiceRestTransport._BaseListContent._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseContentServiceRestTransport._BaseListContent._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.ContentServiceClient.ListContent", + extra={ + "serviceName": "google.ads.admanager.v1.ContentService", + "rpcName": "ListContent", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ContentServiceRestTransport._ListContent._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = content_service.ListContentResponse() + pb_resp = content_service.ListContentResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_content(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_content_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = content_service.ListContentResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.ContentServiceClient.list_content", + extra={ + "serviceName": "google.ads.admanager.v1.ContentService", + "rpcName": "ListContent", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def get_content( + self, + ) -> Callable[[content_service.GetContentRequest], content_messages.Content]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetContent(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_content( + self, + ) -> Callable[ + [content_service.ListContentRequest], content_service.ListContentResponse + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListContent(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseContentServiceRestTransport._BaseGetOperation, ContentServiceRestStub + ): + def __hash__(self): + return hash("ContentServiceRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = ( + _BaseContentServiceRestTransport._BaseGetOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = _BaseContentServiceRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseContentServiceRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.ContentServiceClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.ContentService", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ContentServiceRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.ContentServiceAsyncClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.ContentService", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("ContentServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/transports/rest_base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/transports/rest_base.py new file mode 100644 index 000000000000..718d6b28d58c --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/content_service/transports/rest_base.py @@ -0,0 +1,211 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.ads.admanager_v1.types import content_messages, content_service + +from .base import DEFAULT_CLIENT_INFO, ContentServiceTransport + + +class _BaseContentServiceRestTransport(ContentServiceTransport): + """Base REST backend transport for ContentService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetContent: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/content/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = content_service.GetContentRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseContentServiceRestTransport._BaseGetContent._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListContent: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=networks/*}/content", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = content_service.ListContentRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseContentServiceRestTransport._BaseListContent._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/operations/reports/runs/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseContentServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/__init__.py new file mode 100644 index 000000000000..fec6940da12d --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 CreativeTemplateServiceClient + +__all__ = ("CreativeTemplateServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/client.py new file mode 100644 index 000000000000..111b0c089b5f --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/client.py @@ -0,0 +1,1055 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +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.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version + +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.longrunning import operations_pb2 # type: ignore + +from google.ads.admanager_v1.services.creative_template_service import pagers +from google.ads.admanager_v1.types import ( + creative_template_enums, + creative_template_messages, + creative_template_service, +) + +from .transports.base import DEFAULT_CLIENT_INFO, CreativeTemplateServiceTransport +from .transports.rest import CreativeTemplateServiceRestTransport + + +class CreativeTemplateServiceClientMeta(type): + """Metaclass for the CreativeTemplateService 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[CreativeTemplateServiceTransport]] + _transport_registry["rest"] = CreativeTemplateServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CreativeTemplateServiceTransport]: + """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 CreativeTemplateServiceClient(metaclass=CreativeTemplateServiceClientMeta): + """Provides methods for handling ``CreativeTemplate`` objects.""" + + @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 = "admanager.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "admanager.{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: + CreativeTemplateServiceClient: 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: + CreativeTemplateServiceClient: 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) -> CreativeTemplateServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CreativeTemplateServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def creative_template_path( + network_code: str, + creative_template: str, + ) -> str: + """Returns a fully-qualified creative_template string.""" + return "networks/{network_code}/creativeTemplates/{creative_template}".format( + network_code=network_code, + creative_template=creative_template, + ) + + @staticmethod + def parse_creative_template_path(path: str) -> Dict[str, str]: + """Parses a creative_template path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/creativeTemplates/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def network_path( + network_code: str, + ) -> str: + """Returns a fully-qualified network string.""" + return "networks/{network_code}".format( + network_code=network_code, + ) + + @staticmethod + def parse_network_path(path: str) -> Dict[str, str]: + """Parses a network path into its component segments.""" + m = re.match(r"^networks/(?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 = CreativeTemplateServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CreativeTemplateServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + CreativeTemplateServiceClient._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 = CreativeTemplateServiceClient._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, + CreativeTemplateServiceTransport, + Callable[..., CreativeTemplateServiceTransport], + ] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the creative template 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,CreativeTemplateServiceTransport,Callable[..., CreativeTemplateServiceTransport]]]): + 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 CreativeTemplateServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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, + ) = CreativeTemplateServiceClient._read_environment_variables() + self._client_cert_source = ( + CreativeTemplateServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = CreativeTemplateServiceClient._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, CreativeTemplateServiceTransport) + if transport_provided: + # transport is a CreativeTemplateServiceTransport 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(CreativeTemplateServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CreativeTemplateServiceClient._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[CreativeTemplateServiceTransport], + Callable[..., CreativeTemplateServiceTransport], + ] = ( + CreativeTemplateServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., CreativeTemplateServiceTransport], 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.admanager_v1.CreativeTemplateServiceClient`.", + extra={ + "serviceName": "google.ads.admanager.v1.CreativeTemplateService", + "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.admanager.v1.CreativeTemplateService", + "credentialsType": None, + }, + ) + + def get_creative_template( + self, + request: Optional[ + Union[creative_template_service.GetCreativeTemplateRequest, dict] + ] = None, + *, + 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]]] = (), + ) -> creative_template_messages.CreativeTemplate: + r"""API to retrieve a ``CreativeTemplate`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_get_creative_template(): + # Create a client + client = admanager_v1.CreativeTemplateServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetCreativeTemplateRequest( + name="name_value", + ) + + # Make the request + response = client.get_creative_template(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.GetCreativeTemplateRequest, dict]): + The request object. Request object for ``GetCreativeTemplate`` method. + name (str): + Required. The resource name of the CreativeTemplate. + Format: + ``networks/{network_code}/creativeTemplates/{creative_template_id}`` + + This corresponds to the ``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.admanager_v1.types.CreativeTemplate: + A template that can be used to create a + [TemplateCreative][]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, creative_template_service.GetCreativeTemplateRequest + ): + request = creative_template_service.GetCreativeTemplateRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_creative_template] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_creative_templates( + self, + request: Optional[ + Union[creative_template_service.ListCreativeTemplatesRequest, dict] + ] = None, + *, + parent: 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.ListCreativeTemplatesPager: + r"""API to retrieve a list of ``CreativeTemplate`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_list_creative_templates(): + # Create a client + client = admanager_v1.CreativeTemplateServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListCreativeTemplatesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_creative_templates(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.ListCreativeTemplatesRequest, dict]): + The request object. Request object for ``ListCreativeTemplates`` method. + parent (str): + Required. The parent, which owns this collection of + CreativeTemplates. Format: ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.services.creative_template_service.pagers.ListCreativeTemplatesPager: + Response object for ListCreativeTemplatesRequest containing matching + CreativeTemplate objects. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, creative_template_service.ListCreativeTemplatesRequest + ): + request = creative_template_service.ListCreativeTemplatesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_creative_templates] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.ListCreativeTemplatesPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CreativeTemplateServiceClient": + 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() + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CreativeTemplateServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/pagers.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/pagers.py new file mode 100644 index 000000000000..4ec78308875f --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/pagers.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 typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +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 + +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.admanager_v1.types import ( + creative_template_messages, + creative_template_service, +) + + +class ListCreativeTemplatesPager: + """A pager for iterating through ``list_creative_templates`` requests. + + This class thinly wraps an initial + :class:`google.ads.admanager_v1.types.ListCreativeTemplatesResponse` object, and + provides an ``__iter__`` method to iterate through its + ``creative_templates`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListCreativeTemplates`` requests and continue to iterate + through the ``creative_templates`` field on the + corresponding responses. + + All the usual :class:`google.ads.admanager_v1.types.ListCreativeTemplatesResponse` + 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[..., creative_template_service.ListCreativeTemplatesResponse], + request: creative_template_service.ListCreativeTemplatesRequest, + response: creative_template_service.ListCreativeTemplatesResponse, + *, + 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.admanager_v1.types.ListCreativeTemplatesRequest): + The initial request object. + response (google.ads.admanager_v1.types.ListCreativeTemplatesResponse): + 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 = creative_template_service.ListCreativeTemplatesRequest(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[creative_template_service.ListCreativeTemplatesResponse]: + 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[creative_template_messages.CreativeTemplate]: + for page in self.pages: + yield from page.creative_templates + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/transports/README.rst b/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/transports/README.rst new file mode 100644 index 000000000000..f07f72e90564 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`CreativeTemplateServiceTransport` is the ABC for all transports. +- public child `CreativeTemplateServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `CreativeTemplateServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseCreativeTemplateServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `CreativeTemplateServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/transports/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/transports/__init__.py new file mode 100644 index 000000000000..760dd54dd935 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/transports/__init__.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 typing import Dict, Type + +from .base import CreativeTemplateServiceTransport +from .rest import ( + CreativeTemplateServiceRestInterceptor, + CreativeTemplateServiceRestTransport, +) + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CreativeTemplateServiceTransport]] +_transport_registry["rest"] = CreativeTemplateServiceRestTransport + +__all__ = ( + "CreativeTemplateServiceTransport", + "CreativeTemplateServiceRestTransport", + "CreativeTemplateServiceRestInterceptor", +) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/transports/base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/transports/base.py new file mode 100644 index 000000000000..c3c4f22def3e --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/transports/base.py @@ -0,0 +1,204 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version +from google.ads.admanager_v1.types import ( + creative_template_messages, + creative_template_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 CreativeTemplateServiceTransport(abc.ABC): + """Abstract transport class for CreativeTemplateService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/admanager",) + + DEFAULT_HOST: str = "admanager.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: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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_creative_template: gapic_v1.method.wrap_method( + self.get_creative_template, + default_timeout=None, + client_info=client_info, + ), + self.list_creative_templates: gapic_v1.method.wrap_method( + self.list_creative_templates, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + 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_creative_template( + self, + ) -> Callable[ + [creative_template_service.GetCreativeTemplateRequest], + Union[ + creative_template_messages.CreativeTemplate, + Awaitable[creative_template_messages.CreativeTemplate], + ], + ]: + raise NotImplementedError() + + @property + def list_creative_templates( + self, + ) -> Callable[ + [creative_template_service.ListCreativeTemplatesRequest], + Union[ + creative_template_service.ListCreativeTemplatesResponse, + Awaitable[creative_template_service.ListCreativeTemplatesResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CreativeTemplateServiceTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/transports/rest.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/transports/rest.py new file mode 100644 index 000000000000..22b568cbabf4 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/transports/rest.py @@ -0,0 +1,795 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.ads.admanager_v1.types import ( + creative_template_messages, + creative_template_service, +) + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseCreativeTemplateServiceRestTransport + +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 = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CreativeTemplateServiceRestInterceptor: + """Interceptor for CreativeTemplateService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the CreativeTemplateServiceRestTransport. + + .. code-block:: python + class MyCustomCreativeTemplateServiceInterceptor(CreativeTemplateServiceRestInterceptor): + def pre_get_creative_template(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_creative_template(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_creative_templates(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_creative_templates(self, response): + logging.log(f"Received response: {response}") + return response + + transport = CreativeTemplateServiceRestTransport(interceptor=MyCustomCreativeTemplateServiceInterceptor()) + client = CreativeTemplateServiceClient(transport=transport) + + + """ + + def pre_get_creative_template( + self, + request: creative_template_service.GetCreativeTemplateRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + creative_template_service.GetCreativeTemplateRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for get_creative_template + + Override in a subclass to manipulate the request or metadata + before they are sent to the CreativeTemplateService server. + """ + return request, metadata + + def post_get_creative_template( + self, response: creative_template_messages.CreativeTemplate + ) -> creative_template_messages.CreativeTemplate: + """Post-rpc interceptor for get_creative_template + + DEPRECATED. Please use the `post_get_creative_template_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the CreativeTemplateService server but before + it is returned to user code. This `post_get_creative_template` interceptor runs + before the `post_get_creative_template_with_metadata` interceptor. + """ + return response + + def post_get_creative_template_with_metadata( + self, + response: creative_template_messages.CreativeTemplate, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + creative_template_messages.CreativeTemplate, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for get_creative_template + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CreativeTemplateService server but before it is returned to user code. + + We recommend only using this `post_get_creative_template_with_metadata` + interceptor in new development instead of the `post_get_creative_template` interceptor. + When both interceptors are used, this `post_get_creative_template_with_metadata` interceptor runs after the + `post_get_creative_template` interceptor. The (possibly modified) response returned by + `post_get_creative_template` will be passed to + `post_get_creative_template_with_metadata`. + """ + return response, metadata + + def pre_list_creative_templates( + self, + request: creative_template_service.ListCreativeTemplatesRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + creative_template_service.ListCreativeTemplatesRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for list_creative_templates + + Override in a subclass to manipulate the request or metadata + before they are sent to the CreativeTemplateService server. + """ + return request, metadata + + def post_list_creative_templates( + self, response: creative_template_service.ListCreativeTemplatesResponse + ) -> creative_template_service.ListCreativeTemplatesResponse: + """Post-rpc interceptor for list_creative_templates + + DEPRECATED. Please use the `post_list_creative_templates_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the CreativeTemplateService server but before + it is returned to user code. This `post_list_creative_templates` interceptor runs + before the `post_list_creative_templates_with_metadata` interceptor. + """ + return response + + def post_list_creative_templates_with_metadata( + self, + response: creative_template_service.ListCreativeTemplatesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + creative_template_service.ListCreativeTemplatesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_creative_templates + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CreativeTemplateService server but before it is returned to user code. + + We recommend only using this `post_list_creative_templates_with_metadata` + interceptor in new development instead of the `post_list_creative_templates` interceptor. + When both interceptors are used, this `post_list_creative_templates_with_metadata` interceptor runs after the + `post_list_creative_templates` interceptor. The (possibly modified) response returned by + `post_list_creative_templates` will be passed to + `post_list_creative_templates_with_metadata`. + """ + return response, metadata + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the CreativeTemplateService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the CreativeTemplateService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class CreativeTemplateServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: CreativeTemplateServiceRestInterceptor + + +class CreativeTemplateServiceRestTransport(_BaseCreativeTemplateServiceRestTransport): + """REST backend synchronous transport for CreativeTemplateService. + + Provides methods for handling ``CreativeTemplate`` objects. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[CreativeTemplateServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or CreativeTemplateServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _GetCreativeTemplate( + _BaseCreativeTemplateServiceRestTransport._BaseGetCreativeTemplate, + CreativeTemplateServiceRestStub, + ): + def __hash__(self): + return hash("CreativeTemplateServiceRestTransport.GetCreativeTemplate") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: creative_template_service.GetCreativeTemplateRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> creative_template_messages.CreativeTemplate: + r"""Call the get creative template method over HTTP. + + Args: + request (~.creative_template_service.GetCreativeTemplateRequest): + The request object. Request object for ``GetCreativeTemplate`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.creative_template_messages.CreativeTemplate: + A template that can be used to create a + [TemplateCreative][]. + + """ + + http_options = ( + _BaseCreativeTemplateServiceRestTransport._BaseGetCreativeTemplate._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_creative_template( + request, metadata + ) + transcoded_request = _BaseCreativeTemplateServiceRestTransport._BaseGetCreativeTemplate._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseCreativeTemplateServiceRestTransport._BaseGetCreativeTemplate._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.CreativeTemplateServiceClient.GetCreativeTemplate", + extra={ + "serviceName": "google.ads.admanager.v1.CreativeTemplateService", + "rpcName": "GetCreativeTemplate", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + CreativeTemplateServiceRestTransport._GetCreativeTemplate._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = creative_template_messages.CreativeTemplate() + pb_resp = creative_template_messages.CreativeTemplate.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_creative_template(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_creative_template_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + creative_template_messages.CreativeTemplate.to_json(response) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.CreativeTemplateServiceClient.get_creative_template", + extra={ + "serviceName": "google.ads.admanager.v1.CreativeTemplateService", + "rpcName": "GetCreativeTemplate", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListCreativeTemplates( + _BaseCreativeTemplateServiceRestTransport._BaseListCreativeTemplates, + CreativeTemplateServiceRestStub, + ): + def __hash__(self): + return hash("CreativeTemplateServiceRestTransport.ListCreativeTemplates") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: creative_template_service.ListCreativeTemplatesRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> creative_template_service.ListCreativeTemplatesResponse: + r"""Call the list creative templates method over HTTP. + + Args: + request (~.creative_template_service.ListCreativeTemplatesRequest): + The request object. Request object for ``ListCreativeTemplates`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.creative_template_service.ListCreativeTemplatesResponse: + Response object for ``ListCreativeTemplatesRequest`` + containing matching ``CreativeTemplate`` objects. + + """ + + http_options = ( + _BaseCreativeTemplateServiceRestTransport._BaseListCreativeTemplates._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_creative_templates( + request, metadata + ) + transcoded_request = _BaseCreativeTemplateServiceRestTransport._BaseListCreativeTemplates._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseCreativeTemplateServiceRestTransport._BaseListCreativeTemplates._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.CreativeTemplateServiceClient.ListCreativeTemplates", + extra={ + "serviceName": "google.ads.admanager.v1.CreativeTemplateService", + "rpcName": "ListCreativeTemplates", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = CreativeTemplateServiceRestTransport._ListCreativeTemplates._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = creative_template_service.ListCreativeTemplatesResponse() + pb_resp = creative_template_service.ListCreativeTemplatesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_creative_templates(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_creative_templates_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + creative_template_service.ListCreativeTemplatesResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.CreativeTemplateServiceClient.list_creative_templates", + extra={ + "serviceName": "google.ads.admanager.v1.CreativeTemplateService", + "rpcName": "ListCreativeTemplates", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def get_creative_template( + self, + ) -> Callable[ + [creative_template_service.GetCreativeTemplateRequest], + creative_template_messages.CreativeTemplate, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetCreativeTemplate(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_creative_templates( + self, + ) -> Callable[ + [creative_template_service.ListCreativeTemplatesRequest], + creative_template_service.ListCreativeTemplatesResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListCreativeTemplates(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseCreativeTemplateServiceRestTransport._BaseGetOperation, + CreativeTemplateServiceRestStub, + ): + def __hash__(self): + return hash("CreativeTemplateServiceRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = ( + _BaseCreativeTemplateServiceRestTransport._BaseGetOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = _BaseCreativeTemplateServiceRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseCreativeTemplateServiceRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.CreativeTemplateServiceClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.CreativeTemplateService", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = CreativeTemplateServiceRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.CreativeTemplateServiceAsyncClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.CreativeTemplateService", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("CreativeTemplateServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/transports/rest_base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/transports/rest_base.py new file mode 100644 index 000000000000..ff36f4a1c89f --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/creative_template_service/transports/rest_base.py @@ -0,0 +1,218 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.ads.admanager_v1.types import ( + creative_template_messages, + creative_template_service, +) + +from .base import DEFAULT_CLIENT_INFO, CreativeTemplateServiceTransport + + +class _BaseCreativeTemplateServiceRestTransport(CreativeTemplateServiceTransport): + """Base REST backend transport for CreativeTemplateService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetCreativeTemplate: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/creativeTemplates/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = creative_template_service.GetCreativeTemplateRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseCreativeTemplateServiceRestTransport._BaseGetCreativeTemplate._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListCreativeTemplates: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=networks/*}/creativeTemplates", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = creative_template_service.ListCreativeTemplatesRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseCreativeTemplateServiceRestTransport._BaseListCreativeTemplates._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/operations/reports/runs/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseCreativeTemplateServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/custom_field_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/custom_field_service/client.py index a76d64f2c3b7..5f3317b7b769 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/services/custom_field_service/client.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/custom_field_service/client.py @@ -62,6 +62,7 @@ _LOGGER = std_logging.getLogger(__name__) from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore from google.ads.admanager_v1.services.custom_field_service import pagers from google.ads.admanager_v1.types import ( @@ -962,6 +963,739 @@ def sample_list_custom_fields(): # Done; return the response. return response + def create_custom_field( + self, + request: Optional[ + Union[custom_field_service.CreateCustomFieldRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + custom_field: Optional[custom_field_messages.CustomField] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> custom_field_messages.CustomField: + r"""API to create a ``CustomField`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_create_custom_field(): + # Create a client + client = admanager_v1.CustomFieldServiceClient() + + # Initialize request argument(s) + request = admanager_v1.CreateCustomFieldRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_custom_field(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.CreateCustomFieldRequest, dict]): + The request object. Request object for ``CreateCustomField`` method. + parent (str): + Required. The parent resource where this ``CustomField`` + will be created. Format: ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + custom_field (google.ads.admanager_v1.types.CustomField): + Required. The ``CustomField`` to create. + This corresponds to the ``custom_field`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.CustomField: + An additional, user-created field on + an entity. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, custom_field] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request 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_field_service.CreateCustomFieldRequest): + request = custom_field_service.CreateCustomFieldRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if custom_field is not None: + request.custom_field = custom_field + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_custom_field] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def batch_create_custom_fields( + self, + request: Optional[ + Union[custom_field_service.BatchCreateCustomFieldsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + requests: Optional[ + MutableSequence[custom_field_service.CreateCustomFieldRequest] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> custom_field_service.BatchCreateCustomFieldsResponse: + r"""API to batch create ``CustomField`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_batch_create_custom_fields(): + # Create a client + client = admanager_v1.CustomFieldServiceClient() + + # Initialize request argument(s) + requests = admanager_v1.CreateCustomFieldRequest() + requests.parent = "parent_value" + + request = admanager_v1.BatchCreateCustomFieldsRequest( + parent="parent_value", + requests=requests, + ) + + # Make the request + response = client.batch_create_custom_fields(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.BatchCreateCustomFieldsRequest, dict]): + The request object. Request object for ``BatchCreateCustomFields`` method. + parent (str): + Required. The parent resource where ``CustomFields`` + will be created. Format: ``networks/{network_code}`` The + parent field in the CreateCustomFieldRequest must match + this field. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + requests (MutableSequence[google.ads.admanager_v1.types.CreateCustomFieldRequest]): + Required. The ``CustomField`` objects to create. A + maximum of 100 objects can be created in a batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.BatchCreateCustomFieldsResponse: + Response object for BatchCreateCustomFields method. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, requests] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request 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_field_service.BatchCreateCustomFieldsRequest): + request = custom_field_service.BatchCreateCustomFieldsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.batch_create_custom_fields + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe 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_custom_field( + self, + request: Optional[ + Union[custom_field_service.UpdateCustomFieldRequest, dict] + ] = None, + *, + custom_field: Optional[custom_field_messages.CustomField] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> custom_field_messages.CustomField: + r"""API to update a ``CustomField`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_update_custom_field(): + # Create a client + client = admanager_v1.CustomFieldServiceClient() + + # Initialize request argument(s) + request = admanager_v1.UpdateCustomFieldRequest( + ) + + # Make the request + response = client.update_custom_field(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.UpdateCustomFieldRequest, dict]): + The request object. Request object for ``UpdateCustomField`` method. + custom_field (google.ads.admanager_v1.types.CustomField): + Required. The ``CustomField`` to update. + + The ``CustomField``'s ``name`` is used to identify the + ``CustomField`` to update. + + This corresponds to the ``custom_field`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Required. The list of fields to + update. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.CustomField: + An additional, user-created field on + an entity. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [custom_field, update_mask] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request 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_field_service.UpdateCustomFieldRequest): + request = custom_field_service.UpdateCustomFieldRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if custom_field is not None: + request.custom_field = custom_field + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_custom_field] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("custom_field.name", request.custom_field.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 batch_update_custom_fields( + self, + request: Optional[ + Union[custom_field_service.BatchUpdateCustomFieldsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + requests: Optional[ + MutableSequence[custom_field_service.UpdateCustomFieldRequest] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> custom_field_service.BatchUpdateCustomFieldsResponse: + r"""API to batch update ``CustomField`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_batch_update_custom_fields(): + # Create a client + client = admanager_v1.CustomFieldServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchUpdateCustomFieldsRequest( + parent="parent_value", + ) + + # Make the request + response = client.batch_update_custom_fields(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.BatchUpdateCustomFieldsRequest, dict]): + The request object. Request object for ``BatchUpdateCustomFields`` method. + parent (str): + Required. The parent resource where ``CustomFields`` + will be updated. Format: ``networks/{network_code}`` The + parent field in the UpdateCustomFieldRequest must match + this field. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + requests (MutableSequence[google.ads.admanager_v1.types.UpdateCustomFieldRequest]): + Required. The ``CustomField`` objects to update. A + maximum of 100 objects can be updated in a batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.BatchUpdateCustomFieldsResponse: + Response object for BatchUpdateCustomFields method. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, requests] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request 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_field_service.BatchUpdateCustomFieldsRequest): + request = custom_field_service.BatchUpdateCustomFieldsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.batch_update_custom_fields + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def batch_activate_custom_fields( + self, + request: Optional[ + Union[custom_field_service.BatchActivateCustomFieldsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + names: 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]]] = (), + ) -> custom_field_service.BatchActivateCustomFieldsResponse: + r"""Activates a list of ``CustomField`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_batch_activate_custom_fields(): + # Create a client + client = admanager_v1.CustomFieldServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchActivateCustomFieldsRequest( + parent="parent_value", + names=['names_value1', 'names_value2'], + ) + + # Make the request + response = client.batch_activate_custom_fields(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.BatchActivateCustomFieldsRequest, dict]): + The request object. Request message for ``BatchActivateCustomFields`` + method. + parent (str): + Required. Format: ``networks/{network_code}`` + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + names (MutableSequence[str]): + Required. The resource names of the ``CustomField`` + objects to activate. Format: + ``networks/{network_code}/customFields/{custom_field_id}`` + + This corresponds to the ``names`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.BatchActivateCustomFieldsResponse: + Response object for BatchActivateCustomFields method. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, names] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request 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_field_service.BatchActivateCustomFieldsRequest + ): + request = custom_field_service.BatchActivateCustomFieldsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if names is not None: + request.names = names + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.batch_activate_custom_fields + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def batch_deactivate_custom_fields( + self, + request: Optional[ + Union[custom_field_service.BatchDeactivateCustomFieldsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + names: 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]]] = (), + ) -> custom_field_service.BatchDeactivateCustomFieldsResponse: + r"""Deactivates a list of ``CustomField`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_batch_deactivate_custom_fields(): + # Create a client + client = admanager_v1.CustomFieldServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchDeactivateCustomFieldsRequest( + parent="parent_value", + names=['names_value1', 'names_value2'], + ) + + # Make the request + response = client.batch_deactivate_custom_fields(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.BatchDeactivateCustomFieldsRequest, dict]): + The request object. Request message for ``BatchDeactivateCustomFields`` + method. + parent (str): + Required. Format: ``networks/{network_code}`` + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + names (MutableSequence[str]): + Required. The resource names of the ``CustomField`` + objects to deactivate. Format: + ``networks/{network_code}/customFields/{custom_field_id}`` + + This corresponds to the ``names`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.BatchDeactivateCustomFieldsResponse: + Response object for BatchDeactivateCustomFields method. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, names] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request 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_field_service.BatchDeactivateCustomFieldsRequest + ): + request = custom_field_service.BatchDeactivateCustomFieldsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if names is not None: + request.names = names + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.batch_deactivate_custom_fields + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe 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) -> "CustomFieldServiceClient": return self diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/custom_field_service/transports/base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/custom_field_service/transports/base.py index b0e54d01e5be..2ff84ea94648 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/services/custom_field_service/transports/base.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/custom_field_service/transports/base.py @@ -144,6 +144,36 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.create_custom_field: gapic_v1.method.wrap_method( + self.create_custom_field, + default_timeout=None, + client_info=client_info, + ), + self.batch_create_custom_fields: gapic_v1.method.wrap_method( + self.batch_create_custom_fields, + default_timeout=None, + client_info=client_info, + ), + self.update_custom_field: gapic_v1.method.wrap_method( + self.update_custom_field, + default_timeout=None, + client_info=client_info, + ), + self.batch_update_custom_fields: gapic_v1.method.wrap_method( + self.batch_update_custom_fields, + default_timeout=None, + client_info=client_info, + ), + self.batch_activate_custom_fields: gapic_v1.method.wrap_method( + self.batch_activate_custom_fields, + default_timeout=None, + client_info=client_info, + ), + self.batch_deactivate_custom_fields: gapic_v1.method.wrap_method( + self.batch_deactivate_custom_fields, + default_timeout=None, + client_info=client_info, + ), self.get_operation: gapic_v1.method.wrap_method( self.get_operation, default_timeout=None, @@ -184,6 +214,78 @@ def list_custom_fields( ]: raise NotImplementedError() + @property + def create_custom_field( + self, + ) -> Callable[ + [custom_field_service.CreateCustomFieldRequest], + Union[ + custom_field_messages.CustomField, + Awaitable[custom_field_messages.CustomField], + ], + ]: + raise NotImplementedError() + + @property + def batch_create_custom_fields( + self, + ) -> Callable[ + [custom_field_service.BatchCreateCustomFieldsRequest], + Union[ + custom_field_service.BatchCreateCustomFieldsResponse, + Awaitable[custom_field_service.BatchCreateCustomFieldsResponse], + ], + ]: + raise NotImplementedError() + + @property + def update_custom_field( + self, + ) -> Callable[ + [custom_field_service.UpdateCustomFieldRequest], + Union[ + custom_field_messages.CustomField, + Awaitable[custom_field_messages.CustomField], + ], + ]: + raise NotImplementedError() + + @property + def batch_update_custom_fields( + self, + ) -> Callable[ + [custom_field_service.BatchUpdateCustomFieldsRequest], + Union[ + custom_field_service.BatchUpdateCustomFieldsResponse, + Awaitable[custom_field_service.BatchUpdateCustomFieldsResponse], + ], + ]: + raise NotImplementedError() + + @property + def batch_activate_custom_fields( + self, + ) -> Callable[ + [custom_field_service.BatchActivateCustomFieldsRequest], + Union[ + custom_field_service.BatchActivateCustomFieldsResponse, + Awaitable[custom_field_service.BatchActivateCustomFieldsResponse], + ], + ]: + raise NotImplementedError() + + @property + def batch_deactivate_custom_fields( + self, + ) -> Callable[ + [custom_field_service.BatchDeactivateCustomFieldsRequest], + Union[ + custom_field_service.BatchDeactivateCustomFieldsResponse, + Awaitable[custom_field_service.BatchDeactivateCustomFieldsResponse], + ], + ]: + raise NotImplementedError() + @property def get_operation( self, diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/custom_field_service/transports/rest.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/custom_field_service/transports/rest.py index 4b7c25cea1c9..4b567d05e8e3 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/services/custom_field_service/transports/rest.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/custom_field_service/transports/rest.py @@ -73,6 +73,46 @@ class CustomFieldServiceRestInterceptor: .. code-block:: python class MyCustomCustomFieldServiceInterceptor(CustomFieldServiceRestInterceptor): + def pre_batch_activate_custom_fields(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_activate_custom_fields(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_create_custom_fields(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_create_custom_fields(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_deactivate_custom_fields(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_deactivate_custom_fields(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_update_custom_fields(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_update_custom_fields(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_custom_field(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_custom_field(self, response): + logging.log(f"Received response: {response}") + return response + def pre_get_custom_field(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -89,12 +129,279 @@ def post_list_custom_fields(self, response): logging.log(f"Received response: {response}") return response + def pre_update_custom_field(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_custom_field(self, response): + logging.log(f"Received response: {response}") + return response + transport = CustomFieldServiceRestTransport(interceptor=MyCustomCustomFieldServiceInterceptor()) client = CustomFieldServiceClient(transport=transport) """ + def pre_batch_activate_custom_fields( + self, + request: custom_field_service.BatchActivateCustomFieldsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + custom_field_service.BatchActivateCustomFieldsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for batch_activate_custom_fields + + Override in a subclass to manipulate the request or metadata + before they are sent to the CustomFieldService server. + """ + return request, metadata + + def post_batch_activate_custom_fields( + self, response: custom_field_service.BatchActivateCustomFieldsResponse + ) -> custom_field_service.BatchActivateCustomFieldsResponse: + """Post-rpc interceptor for batch_activate_custom_fields + + DEPRECATED. Please use the `post_batch_activate_custom_fields_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the CustomFieldService server but before + it is returned to user code. This `post_batch_activate_custom_fields` interceptor runs + before the `post_batch_activate_custom_fields_with_metadata` interceptor. + """ + return response + + def post_batch_activate_custom_fields_with_metadata( + self, + response: custom_field_service.BatchActivateCustomFieldsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + custom_field_service.BatchActivateCustomFieldsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for batch_activate_custom_fields + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CustomFieldService server but before it is returned to user code. + + We recommend only using this `post_batch_activate_custom_fields_with_metadata` + interceptor in new development instead of the `post_batch_activate_custom_fields` interceptor. + When both interceptors are used, this `post_batch_activate_custom_fields_with_metadata` interceptor runs after the + `post_batch_activate_custom_fields` interceptor. The (possibly modified) response returned by + `post_batch_activate_custom_fields` will be passed to + `post_batch_activate_custom_fields_with_metadata`. + """ + return response, metadata + + def pre_batch_create_custom_fields( + self, + request: custom_field_service.BatchCreateCustomFieldsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + custom_field_service.BatchCreateCustomFieldsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for batch_create_custom_fields + + Override in a subclass to manipulate the request or metadata + before they are sent to the CustomFieldService server. + """ + return request, metadata + + def post_batch_create_custom_fields( + self, response: custom_field_service.BatchCreateCustomFieldsResponse + ) -> custom_field_service.BatchCreateCustomFieldsResponse: + """Post-rpc interceptor for batch_create_custom_fields + + DEPRECATED. Please use the `post_batch_create_custom_fields_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the CustomFieldService server but before + it is returned to user code. This `post_batch_create_custom_fields` interceptor runs + before the `post_batch_create_custom_fields_with_metadata` interceptor. + """ + return response + + def post_batch_create_custom_fields_with_metadata( + self, + response: custom_field_service.BatchCreateCustomFieldsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + custom_field_service.BatchCreateCustomFieldsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for batch_create_custom_fields + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CustomFieldService server but before it is returned to user code. + + We recommend only using this `post_batch_create_custom_fields_with_metadata` + interceptor in new development instead of the `post_batch_create_custom_fields` interceptor. + When both interceptors are used, this `post_batch_create_custom_fields_with_metadata` interceptor runs after the + `post_batch_create_custom_fields` interceptor. The (possibly modified) response returned by + `post_batch_create_custom_fields` will be passed to + `post_batch_create_custom_fields_with_metadata`. + """ + return response, metadata + + def pre_batch_deactivate_custom_fields( + self, + request: custom_field_service.BatchDeactivateCustomFieldsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + custom_field_service.BatchDeactivateCustomFieldsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for batch_deactivate_custom_fields + + Override in a subclass to manipulate the request or metadata + before they are sent to the CustomFieldService server. + """ + return request, metadata + + def post_batch_deactivate_custom_fields( + self, response: custom_field_service.BatchDeactivateCustomFieldsResponse + ) -> custom_field_service.BatchDeactivateCustomFieldsResponse: + """Post-rpc interceptor for batch_deactivate_custom_fields + + DEPRECATED. Please use the `post_batch_deactivate_custom_fields_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the CustomFieldService server but before + it is returned to user code. This `post_batch_deactivate_custom_fields` interceptor runs + before the `post_batch_deactivate_custom_fields_with_metadata` interceptor. + """ + return response + + def post_batch_deactivate_custom_fields_with_metadata( + self, + response: custom_field_service.BatchDeactivateCustomFieldsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + custom_field_service.BatchDeactivateCustomFieldsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for batch_deactivate_custom_fields + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CustomFieldService server but before it is returned to user code. + + We recommend only using this `post_batch_deactivate_custom_fields_with_metadata` + interceptor in new development instead of the `post_batch_deactivate_custom_fields` interceptor. + When both interceptors are used, this `post_batch_deactivate_custom_fields_with_metadata` interceptor runs after the + `post_batch_deactivate_custom_fields` interceptor. The (possibly modified) response returned by + `post_batch_deactivate_custom_fields` will be passed to + `post_batch_deactivate_custom_fields_with_metadata`. + """ + return response, metadata + + def pre_batch_update_custom_fields( + self, + request: custom_field_service.BatchUpdateCustomFieldsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + custom_field_service.BatchUpdateCustomFieldsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for batch_update_custom_fields + + Override in a subclass to manipulate the request or metadata + before they are sent to the CustomFieldService server. + """ + return request, metadata + + def post_batch_update_custom_fields( + self, response: custom_field_service.BatchUpdateCustomFieldsResponse + ) -> custom_field_service.BatchUpdateCustomFieldsResponse: + """Post-rpc interceptor for batch_update_custom_fields + + DEPRECATED. Please use the `post_batch_update_custom_fields_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the CustomFieldService server but before + it is returned to user code. This `post_batch_update_custom_fields` interceptor runs + before the `post_batch_update_custom_fields_with_metadata` interceptor. + """ + return response + + def post_batch_update_custom_fields_with_metadata( + self, + response: custom_field_service.BatchUpdateCustomFieldsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + custom_field_service.BatchUpdateCustomFieldsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for batch_update_custom_fields + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CustomFieldService server but before it is returned to user code. + + We recommend only using this `post_batch_update_custom_fields_with_metadata` + interceptor in new development instead of the `post_batch_update_custom_fields` interceptor. + When both interceptors are used, this `post_batch_update_custom_fields_with_metadata` interceptor runs after the + `post_batch_update_custom_fields` interceptor. The (possibly modified) response returned by + `post_batch_update_custom_fields` will be passed to + `post_batch_update_custom_fields_with_metadata`. + """ + return response, metadata + + def pre_create_custom_field( + self, + request: custom_field_service.CreateCustomFieldRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + custom_field_service.CreateCustomFieldRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for create_custom_field + + Override in a subclass to manipulate the request or metadata + before they are sent to the CustomFieldService server. + """ + return request, metadata + + def post_create_custom_field( + self, response: custom_field_messages.CustomField + ) -> custom_field_messages.CustomField: + """Post-rpc interceptor for create_custom_field + + DEPRECATED. Please use the `post_create_custom_field_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the CustomFieldService server but before + it is returned to user code. This `post_create_custom_field` interceptor runs + before the `post_create_custom_field_with_metadata` interceptor. + """ + return response + + def post_create_custom_field_with_metadata( + self, + response: custom_field_messages.CustomField, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + custom_field_messages.CustomField, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for create_custom_field + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CustomFieldService server but before it is returned to user code. + + We recommend only using this `post_create_custom_field_with_metadata` + interceptor in new development instead of the `post_create_custom_field` interceptor. + When both interceptors are used, this `post_create_custom_field_with_metadata` interceptor runs after the + `post_create_custom_field` interceptor. The (possibly modified) response returned by + `post_create_custom_field` will be passed to + `post_create_custom_field_with_metadata`. + """ + return response, metadata + def pre_get_custom_field( self, request: custom_field_service.GetCustomFieldRequest, @@ -198,6 +505,57 @@ def post_list_custom_fields_with_metadata( """ return response, metadata + def pre_update_custom_field( + self, + request: custom_field_service.UpdateCustomFieldRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + custom_field_service.UpdateCustomFieldRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for update_custom_field + + Override in a subclass to manipulate the request or metadata + before they are sent to the CustomFieldService server. + """ + return request, metadata + + def post_update_custom_field( + self, response: custom_field_messages.CustomField + ) -> custom_field_messages.CustomField: + """Post-rpc interceptor for update_custom_field + + DEPRECATED. Please use the `post_update_custom_field_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the CustomFieldService server but before + it is returned to user code. This `post_update_custom_field` interceptor runs + before the `post_update_custom_field_with_metadata` interceptor. + """ + return response + + def post_update_custom_field_with_metadata( + self, + response: custom_field_messages.CustomField, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + custom_field_messages.CustomField, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for update_custom_field + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CustomFieldService server but before it is returned to user code. + + We recommend only using this `post_update_custom_field_with_metadata` + interceptor in new development instead of the `post_update_custom_field` interceptor. + When both interceptors are used, this `post_update_custom_field_with_metadata` interceptor runs after the + `post_update_custom_field` interceptor. The (possibly modified) response returned by + `post_update_custom_field` will be passed to + `post_update_custom_field_with_metadata`. + """ + return response, metadata + def pre_get_operation( self, request: operations_pb2.GetOperationRequest, @@ -260,56 +618,856 @@ def __init__( ) -> None: """Instantiate the transport. - Args: - host (Optional[str]): - The hostname to connect to (default: 'admanager.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or CustomFieldServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _BatchActivateCustomFields( + _BaseCustomFieldServiceRestTransport._BaseBatchActivateCustomFields, + CustomFieldServiceRestStub, + ): + def __hash__(self): + return hash("CustomFieldServiceRestTransport.BatchActivateCustomFields") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: custom_field_service.BatchActivateCustomFieldsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> custom_field_service.BatchActivateCustomFieldsResponse: + r"""Call the batch activate custom + fields method over HTTP. + + Args: + request (~.custom_field_service.BatchActivateCustomFieldsRequest): + The request object. Request message for ``BatchActivateCustomFields`` + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.custom_field_service.BatchActivateCustomFieldsResponse: + Response object for ``BatchActivateCustomFields`` + method. + + """ + + http_options = ( + _BaseCustomFieldServiceRestTransport._BaseBatchActivateCustomFields._get_http_options() + ) + + request, metadata = self._interceptor.pre_batch_activate_custom_fields( + request, metadata + ) + transcoded_request = _BaseCustomFieldServiceRestTransport._BaseBatchActivateCustomFields._get_transcoded_request( + http_options, request + ) + + body = _BaseCustomFieldServiceRestTransport._BaseBatchActivateCustomFields._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseCustomFieldServiceRestTransport._BaseBatchActivateCustomFields._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.CustomFieldServiceClient.BatchActivateCustomFields", + extra={ + "serviceName": "google.ads.admanager.v1.CustomFieldService", + "rpcName": "BatchActivateCustomFields", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = CustomFieldServiceRestTransport._BatchActivateCustomFields._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = custom_field_service.BatchActivateCustomFieldsResponse() + pb_resp = custom_field_service.BatchActivateCustomFieldsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_activate_custom_fields(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_activate_custom_fields_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + custom_field_service.BatchActivateCustomFieldsResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.CustomFieldServiceClient.batch_activate_custom_fields", + extra={ + "serviceName": "google.ads.admanager.v1.CustomFieldService", + "rpcName": "BatchActivateCustomFields", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _BatchCreateCustomFields( + _BaseCustomFieldServiceRestTransport._BaseBatchCreateCustomFields, + CustomFieldServiceRestStub, + ): + def __hash__(self): + return hash("CustomFieldServiceRestTransport.BatchCreateCustomFields") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: custom_field_service.BatchCreateCustomFieldsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> custom_field_service.BatchCreateCustomFieldsResponse: + r"""Call the batch create custom + fields method over HTTP. + + Args: + request (~.custom_field_service.BatchCreateCustomFieldsRequest): + The request object. Request object for ``BatchCreateCustomFields`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.custom_field_service.BatchCreateCustomFieldsResponse: + Response object for ``BatchCreateCustomFields`` method. + """ + + http_options = ( + _BaseCustomFieldServiceRestTransport._BaseBatchCreateCustomFields._get_http_options() + ) + + request, metadata = self._interceptor.pre_batch_create_custom_fields( + request, metadata + ) + transcoded_request = _BaseCustomFieldServiceRestTransport._BaseBatchCreateCustomFields._get_transcoded_request( + http_options, request + ) + + body = _BaseCustomFieldServiceRestTransport._BaseBatchCreateCustomFields._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseCustomFieldServiceRestTransport._BaseBatchCreateCustomFields._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.CustomFieldServiceClient.BatchCreateCustomFields", + extra={ + "serviceName": "google.ads.admanager.v1.CustomFieldService", + "rpcName": "BatchCreateCustomFields", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + CustomFieldServiceRestTransport._BatchCreateCustomFields._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = custom_field_service.BatchCreateCustomFieldsResponse() + pb_resp = custom_field_service.BatchCreateCustomFieldsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_create_custom_fields(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_create_custom_fields_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + custom_field_service.BatchCreateCustomFieldsResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.CustomFieldServiceClient.batch_create_custom_fields", + extra={ + "serviceName": "google.ads.admanager.v1.CustomFieldService", + "rpcName": "BatchCreateCustomFields", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _BatchDeactivateCustomFields( + _BaseCustomFieldServiceRestTransport._BaseBatchDeactivateCustomFields, + CustomFieldServiceRestStub, + ): + def __hash__(self): + return hash("CustomFieldServiceRestTransport.BatchDeactivateCustomFields") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: custom_field_service.BatchDeactivateCustomFieldsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> custom_field_service.BatchDeactivateCustomFieldsResponse: + r"""Call the batch deactivate custom + fields method over HTTP. + + Args: + request (~.custom_field_service.BatchDeactivateCustomFieldsRequest): + The request object. Request message for ``BatchDeactivateCustomFields`` + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.custom_field_service.BatchDeactivateCustomFieldsResponse: + Response object for ``BatchDeactivateCustomFields`` + method. + + """ + + http_options = ( + _BaseCustomFieldServiceRestTransport._BaseBatchDeactivateCustomFields._get_http_options() + ) + + request, metadata = self._interceptor.pre_batch_deactivate_custom_fields( + request, metadata + ) + transcoded_request = _BaseCustomFieldServiceRestTransport._BaseBatchDeactivateCustomFields._get_transcoded_request( + http_options, request + ) + + body = _BaseCustomFieldServiceRestTransport._BaseBatchDeactivateCustomFields._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseCustomFieldServiceRestTransport._BaseBatchDeactivateCustomFields._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.CustomFieldServiceClient.BatchDeactivateCustomFields", + extra={ + "serviceName": "google.ads.admanager.v1.CustomFieldService", + "rpcName": "BatchDeactivateCustomFields", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = CustomFieldServiceRestTransport._BatchDeactivateCustomFields._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = custom_field_service.BatchDeactivateCustomFieldsResponse() + pb_resp = custom_field_service.BatchDeactivateCustomFieldsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_deactivate_custom_fields(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_batch_deactivate_custom_fields_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = custom_field_service.BatchDeactivateCustomFieldsResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.CustomFieldServiceClient.batch_deactivate_custom_fields", + extra={ + "serviceName": "google.ads.admanager.v1.CustomFieldService", + "rpcName": "BatchDeactivateCustomFields", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _BatchUpdateCustomFields( + _BaseCustomFieldServiceRestTransport._BaseBatchUpdateCustomFields, + CustomFieldServiceRestStub, + ): + def __hash__(self): + return hash("CustomFieldServiceRestTransport.BatchUpdateCustomFields") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: custom_field_service.BatchUpdateCustomFieldsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> custom_field_service.BatchUpdateCustomFieldsResponse: + r"""Call the batch update custom + fields method over HTTP. + + Args: + request (~.custom_field_service.BatchUpdateCustomFieldsRequest): + The request object. Request object for ``BatchUpdateCustomFields`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.custom_field_service.BatchUpdateCustomFieldsResponse: + Response object for ``BatchUpdateCustomFields`` method. + """ + + http_options = ( + _BaseCustomFieldServiceRestTransport._BaseBatchUpdateCustomFields._get_http_options() + ) + + request, metadata = self._interceptor.pre_batch_update_custom_fields( + request, metadata + ) + transcoded_request = _BaseCustomFieldServiceRestTransport._BaseBatchUpdateCustomFields._get_transcoded_request( + http_options, request + ) + + body = _BaseCustomFieldServiceRestTransport._BaseBatchUpdateCustomFields._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseCustomFieldServiceRestTransport._BaseBatchUpdateCustomFields._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.CustomFieldServiceClient.BatchUpdateCustomFields", + extra={ + "serviceName": "google.ads.admanager.v1.CustomFieldService", + "rpcName": "BatchUpdateCustomFields", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + CustomFieldServiceRestTransport._BatchUpdateCustomFields._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = custom_field_service.BatchUpdateCustomFieldsResponse() + pb_resp = custom_field_service.BatchUpdateCustomFieldsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_update_custom_fields(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_update_custom_fields_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + custom_field_service.BatchUpdateCustomFieldsResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.CustomFieldServiceClient.batch_update_custom_fields", + extra={ + "serviceName": "google.ads.admanager.v1.CustomFieldService", + "rpcName": "BatchUpdateCustomFields", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _CreateCustomField( + _BaseCustomFieldServiceRestTransport._BaseCreateCustomField, + CustomFieldServiceRestStub, + ): + def __hash__(self): + return hash("CustomFieldServiceRestTransport.CreateCustomField") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: custom_field_service.CreateCustomFieldRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> custom_field_messages.CustomField: + r"""Call the create custom field method over HTTP. + + Args: + request (~.custom_field_service.CreateCustomFieldRequest): + The request object. Request object for ``CreateCustomField`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.custom_field_messages.CustomField: + An additional, user-created field on + an entity. + + """ + + http_options = ( + _BaseCustomFieldServiceRestTransport._BaseCreateCustomField._get_http_options() + ) + + request, metadata = self._interceptor.pre_create_custom_field( + request, metadata + ) + transcoded_request = _BaseCustomFieldServiceRestTransport._BaseCreateCustomField._get_transcoded_request( + http_options, request + ) + + body = _BaseCustomFieldServiceRestTransport._BaseCreateCustomField._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseCustomFieldServiceRestTransport._BaseCreateCustomField._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.CustomFieldServiceClient.CreateCustomField", + extra={ + "serviceName": "google.ads.admanager.v1.CustomFieldService", + "rpcName": "CreateCustomField", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = CustomFieldServiceRestTransport._CreateCustomField._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = custom_field_messages.CustomField() + pb_resp = custom_field_messages.CustomField.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - 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 ``channel`` 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 ``channel`` is provided. - client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client - certificate to configure mutual TLS HTTP channel. It is ignored - if ``channel`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you are developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - url_scheme: the protocol scheme for the API endpoint. Normally - "https", but for testing or local servers, - "http" can be specified. - """ - # Run the base constructor - # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. - # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the - # credentials object - super().__init__( - host=host, - credentials=credentials, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - url_scheme=url_scheme, - api_audience=api_audience, - ) - self._session = AuthorizedSession( - self._credentials, default_host=self.DEFAULT_HOST - ) - if client_cert_source_for_mtls: - self._session.configure_mtls_channel(client_cert_source_for_mtls) - self._interceptor = interceptor or CustomFieldServiceRestInterceptor() - self._prep_wrapped_messages(client_info) + resp = self._interceptor.post_create_custom_field(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_custom_field_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = custom_field_messages.CustomField.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.CustomFieldServiceClient.create_custom_field", + extra={ + "serviceName": "google.ads.admanager.v1.CustomFieldService", + "rpcName": "CreateCustomField", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp class _GetCustomField( _BaseCustomFieldServiceRestTransport._BaseGetCustomField, @@ -613,6 +1771,218 @@ def __call__( ) return resp + class _UpdateCustomField( + _BaseCustomFieldServiceRestTransport._BaseUpdateCustomField, + CustomFieldServiceRestStub, + ): + def __hash__(self): + return hash("CustomFieldServiceRestTransport.UpdateCustomField") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: custom_field_service.UpdateCustomFieldRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> custom_field_messages.CustomField: + r"""Call the update custom field method over HTTP. + + Args: + request (~.custom_field_service.UpdateCustomFieldRequest): + The request object. Request object for ``UpdateCustomField`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.custom_field_messages.CustomField: + An additional, user-created field on + an entity. + + """ + + http_options = ( + _BaseCustomFieldServiceRestTransport._BaseUpdateCustomField._get_http_options() + ) + + request, metadata = self._interceptor.pre_update_custom_field( + request, metadata + ) + transcoded_request = _BaseCustomFieldServiceRestTransport._BaseUpdateCustomField._get_transcoded_request( + http_options, request + ) + + body = _BaseCustomFieldServiceRestTransport._BaseUpdateCustomField._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseCustomFieldServiceRestTransport._BaseUpdateCustomField._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.CustomFieldServiceClient.UpdateCustomField", + extra={ + "serviceName": "google.ads.admanager.v1.CustomFieldService", + "rpcName": "UpdateCustomField", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = CustomFieldServiceRestTransport._UpdateCustomField._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = custom_field_messages.CustomField() + pb_resp = custom_field_messages.CustomField.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_update_custom_field(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_custom_field_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = custom_field_messages.CustomField.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.CustomFieldServiceClient.update_custom_field", + extra={ + "serviceName": "google.ads.admanager.v1.CustomFieldService", + "rpcName": "UpdateCustomField", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def batch_activate_custom_fields( + self, + ) -> Callable[ + [custom_field_service.BatchActivateCustomFieldsRequest], + custom_field_service.BatchActivateCustomFieldsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchActivateCustomFields(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_create_custom_fields( + self, + ) -> Callable[ + [custom_field_service.BatchCreateCustomFieldsRequest], + custom_field_service.BatchCreateCustomFieldsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchCreateCustomFields(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_deactivate_custom_fields( + self, + ) -> Callable[ + [custom_field_service.BatchDeactivateCustomFieldsRequest], + custom_field_service.BatchDeactivateCustomFieldsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchDeactivateCustomFields(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_update_custom_fields( + self, + ) -> Callable[ + [custom_field_service.BatchUpdateCustomFieldsRequest], + custom_field_service.BatchUpdateCustomFieldsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchUpdateCustomFields(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_custom_field( + self, + ) -> Callable[ + [custom_field_service.CreateCustomFieldRequest], + custom_field_messages.CustomField, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateCustomField(self._session, self._host, self._interceptor) # type: ignore + @property def get_custom_field( self, @@ -634,6 +2004,17 @@ def list_custom_fields( # In C++ this would require a dynamic_cast return self._ListCustomFields(self._session, self._host, self._interceptor) # type: ignore + @property + def update_custom_field( + self, + ) -> Callable[ + [custom_field_service.UpdateCustomFieldRequest], + custom_field_messages.CustomField, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateCustomField(self._session, self._host, self._interceptor) # type: ignore + @property def get_operation(self): return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/custom_field_service/transports/rest_base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/custom_field_service/transports/rest_base.py index ec04968ade5e..75ca4728b6a5 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/services/custom_field_service/transports/rest_base.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/custom_field_service/transports/rest_base.py @@ -88,6 +88,295 @@ def __init__( api_audience=api_audience, ) + class _BaseBatchActivateCustomFields: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/customFields:batchActivate", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = custom_field_service.BatchActivateCustomFieldsRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseCustomFieldServiceRestTransport._BaseBatchActivateCustomFields._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseBatchCreateCustomFields: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/customFields:batchCreate", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = custom_field_service.BatchCreateCustomFieldsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseCustomFieldServiceRestTransport._BaseBatchCreateCustomFields._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseBatchDeactivateCustomFields: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/customFields:batchDeactivate", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = custom_field_service.BatchDeactivateCustomFieldsRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseCustomFieldServiceRestTransport._BaseBatchDeactivateCustomFields._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseBatchUpdateCustomFields: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/customFields:batchUpdate", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = custom_field_service.BatchUpdateCustomFieldsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseCustomFieldServiceRestTransport._BaseBatchUpdateCustomFields._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseCreateCustomField: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/customFields", + "body": "custom_field", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = custom_field_service.CreateCustomFieldRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseCustomFieldServiceRestTransport._BaseCreateCustomField._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + class _BaseGetCustomField: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -182,6 +471,65 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params + class _BaseUpdateCustomField: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "updateMask": {}, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v1/{custom_field.name=networks/*/customFields/*}", + "body": "custom_field", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = custom_field_service.UpdateCustomFieldRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseCustomFieldServiceRestTransport._BaseUpdateCustomField._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + class _BaseGetOperation: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/__init__.py new file mode 100644 index 000000000000..2878c88dcd3f --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 DeviceCapabilityServiceClient + +__all__ = ("DeviceCapabilityServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/client.py new file mode 100644 index 000000000000..55de47d45b0d --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_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 ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +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.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version + +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.longrunning import operations_pb2 # type: ignore + +from google.ads.admanager_v1.services.device_capability_service import pagers +from google.ads.admanager_v1.types import ( + device_capability_messages, + device_capability_service, +) + +from .transports.base import DEFAULT_CLIENT_INFO, DeviceCapabilityServiceTransport +from .transports.rest import DeviceCapabilityServiceRestTransport + + +class DeviceCapabilityServiceClientMeta(type): + """Metaclass for the DeviceCapabilityService 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[DeviceCapabilityServiceTransport]] + _transport_registry["rest"] = DeviceCapabilityServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[DeviceCapabilityServiceTransport]: + """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 DeviceCapabilityServiceClient(metaclass=DeviceCapabilityServiceClientMeta): + """Provides methods for handling ``DeviceCapability`` objects.""" + + @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 = "admanager.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "admanager.{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: + DeviceCapabilityServiceClient: 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: + DeviceCapabilityServiceClient: 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) -> DeviceCapabilityServiceTransport: + """Returns the transport used by the client instance. + + Returns: + DeviceCapabilityServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def device_capability_path( + network_code: str, + device_capability: str, + ) -> str: + """Returns a fully-qualified device_capability string.""" + return "networks/{network_code}/deviceCapabilities/{device_capability}".format( + network_code=network_code, + device_capability=device_capability, + ) + + @staticmethod + def parse_device_capability_path(path: str) -> Dict[str, str]: + """Parses a device_capability path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/deviceCapabilities/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def network_path( + network_code: str, + ) -> str: + """Returns a fully-qualified network string.""" + return "networks/{network_code}".format( + network_code=network_code, + ) + + @staticmethod + def parse_network_path(path: str) -> Dict[str, str]: + """Parses a network path into its component segments.""" + m = re.match(r"^networks/(?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 = DeviceCapabilityServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = DeviceCapabilityServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + DeviceCapabilityServiceClient._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 = DeviceCapabilityServiceClient._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, + DeviceCapabilityServiceTransport, + Callable[..., DeviceCapabilityServiceTransport], + ] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the device capability 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,DeviceCapabilityServiceTransport,Callable[..., DeviceCapabilityServiceTransport]]]): + 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 DeviceCapabilityServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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, + ) = DeviceCapabilityServiceClient._read_environment_variables() + self._client_cert_source = ( + DeviceCapabilityServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = DeviceCapabilityServiceClient._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, DeviceCapabilityServiceTransport) + if transport_provided: + # transport is a DeviceCapabilityServiceTransport 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(DeviceCapabilityServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or DeviceCapabilityServiceClient._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[DeviceCapabilityServiceTransport], + Callable[..., DeviceCapabilityServiceTransport], + ] = ( + DeviceCapabilityServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., DeviceCapabilityServiceTransport], 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.admanager_v1.DeviceCapabilityServiceClient`.", + extra={ + "serviceName": "google.ads.admanager.v1.DeviceCapabilityService", + "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.admanager.v1.DeviceCapabilityService", + "credentialsType": None, + }, + ) + + def get_device_capability( + self, + request: Optional[ + Union[device_capability_service.GetDeviceCapabilityRequest, dict] + ] = None, + *, + 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]]] = (), + ) -> device_capability_messages.DeviceCapability: + r"""API to retrieve a ``DeviceCapability`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_get_device_capability(): + # Create a client + client = admanager_v1.DeviceCapabilityServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetDeviceCapabilityRequest( + name="name_value", + ) + + # Make the request + response = client.get_device_capability(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.GetDeviceCapabilityRequest, dict]): + The request object. Request object for ``GetDeviceCapability`` method. + name (str): + Required. The resource name of the DeviceCapability. + Format: + ``networks/{network_code}/deviceCapabilities/{device_capability_id}`` + + This corresponds to the ``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.admanager_v1.types.DeviceCapability: + Represents a device capability. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, device_capability_service.GetDeviceCapabilityRequest + ): + request = device_capability_service.GetDeviceCapabilityRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_device_capability] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_device_capabilities( + self, + request: Optional[ + Union[device_capability_service.ListDeviceCapabilitiesRequest, dict] + ] = None, + *, + parent: 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.ListDeviceCapabilitiesPager: + r"""API to retrieve a list of ``DeviceCapability`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_list_device_capabilities(): + # Create a client + client = admanager_v1.DeviceCapabilityServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListDeviceCapabilitiesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_device_capabilities(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.ListDeviceCapabilitiesRequest, dict]): + The request object. Request object for ``ListDeviceCapabilities`` method. + parent (str): + Required. The parent, which owns this collection of + DeviceCapabilities. Format: ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.services.device_capability_service.pagers.ListDeviceCapabilitiesPager: + Response object for ListDeviceCapabilitiesRequest containing matching + DeviceCapability objects. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, device_capability_service.ListDeviceCapabilitiesRequest + ): + request = device_capability_service.ListDeviceCapabilitiesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_device_capabilities] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.ListDeviceCapabilitiesPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "DeviceCapabilityServiceClient": + 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() + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("DeviceCapabilityServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/pagers.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/pagers.py new file mode 100644 index 000000000000..a69e874671aa --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/pagers.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 typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +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 + +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.admanager_v1.types import ( + device_capability_messages, + device_capability_service, +) + + +class ListDeviceCapabilitiesPager: + """A pager for iterating through ``list_device_capabilities`` requests. + + This class thinly wraps an initial + :class:`google.ads.admanager_v1.types.ListDeviceCapabilitiesResponse` object, and + provides an ``__iter__`` method to iterate through its + ``device_capabilities`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListDeviceCapabilities`` requests and continue to iterate + through the ``device_capabilities`` field on the + corresponding responses. + + All the usual :class:`google.ads.admanager_v1.types.ListDeviceCapabilitiesResponse` + 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[..., device_capability_service.ListDeviceCapabilitiesResponse], + request: device_capability_service.ListDeviceCapabilitiesRequest, + response: device_capability_service.ListDeviceCapabilitiesResponse, + *, + 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.admanager_v1.types.ListDeviceCapabilitiesRequest): + The initial request object. + response (google.ads.admanager_v1.types.ListDeviceCapabilitiesResponse): + 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 = device_capability_service.ListDeviceCapabilitiesRequest(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[device_capability_service.ListDeviceCapabilitiesResponse]: + 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[device_capability_messages.DeviceCapability]: + for page in self.pages: + yield from page.device_capabilities + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/transports/README.rst b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/transports/README.rst new file mode 100644 index 000000000000..1f0d8b349ac9 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`DeviceCapabilityServiceTransport` is the ABC for all transports. +- public child `DeviceCapabilityServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `DeviceCapabilityServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseDeviceCapabilityServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `DeviceCapabilityServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/transports/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/transports/__init__.py new file mode 100644 index 000000000000..96cc6d3d9875 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/transports/__init__.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 typing import Dict, Type + +from .base import DeviceCapabilityServiceTransport +from .rest import ( + DeviceCapabilityServiceRestInterceptor, + DeviceCapabilityServiceRestTransport, +) + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[DeviceCapabilityServiceTransport]] +_transport_registry["rest"] = DeviceCapabilityServiceRestTransport + +__all__ = ( + "DeviceCapabilityServiceTransport", + "DeviceCapabilityServiceRestTransport", + "DeviceCapabilityServiceRestInterceptor", +) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/transports/base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/transports/base.py new file mode 100644 index 000000000000..9b1a45ac6b5a --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/transports/base.py @@ -0,0 +1,204 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version +from google.ads.admanager_v1.types import ( + device_capability_messages, + device_capability_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 DeviceCapabilityServiceTransport(abc.ABC): + """Abstract transport class for DeviceCapabilityService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/admanager",) + + DEFAULT_HOST: str = "admanager.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: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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_device_capability: gapic_v1.method.wrap_method( + self.get_device_capability, + default_timeout=None, + client_info=client_info, + ), + self.list_device_capabilities: gapic_v1.method.wrap_method( + self.list_device_capabilities, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + 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_device_capability( + self, + ) -> Callable[ + [device_capability_service.GetDeviceCapabilityRequest], + Union[ + device_capability_messages.DeviceCapability, + Awaitable[device_capability_messages.DeviceCapability], + ], + ]: + raise NotImplementedError() + + @property + def list_device_capabilities( + self, + ) -> Callable[ + [device_capability_service.ListDeviceCapabilitiesRequest], + Union[ + device_capability_service.ListDeviceCapabilitiesResponse, + Awaitable[device_capability_service.ListDeviceCapabilitiesResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("DeviceCapabilityServiceTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/transports/rest.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/transports/rest.py new file mode 100644 index 000000000000..f5cd40b6d5f2 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/transports/rest.py @@ -0,0 +1,791 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.ads.admanager_v1.types import ( + device_capability_messages, + device_capability_service, +) + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseDeviceCapabilityServiceRestTransport + +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 = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class DeviceCapabilityServiceRestInterceptor: + """Interceptor for DeviceCapabilityService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the DeviceCapabilityServiceRestTransport. + + .. code-block:: python + class MyCustomDeviceCapabilityServiceInterceptor(DeviceCapabilityServiceRestInterceptor): + def pre_get_device_capability(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_device_capability(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_device_capabilities(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_device_capabilities(self, response): + logging.log(f"Received response: {response}") + return response + + transport = DeviceCapabilityServiceRestTransport(interceptor=MyCustomDeviceCapabilityServiceInterceptor()) + client = DeviceCapabilityServiceClient(transport=transport) + + + """ + + def pre_get_device_capability( + self, + request: device_capability_service.GetDeviceCapabilityRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + device_capability_service.GetDeviceCapabilityRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for get_device_capability + + Override in a subclass to manipulate the request or metadata + before they are sent to the DeviceCapabilityService server. + """ + return request, metadata + + def post_get_device_capability( + self, response: device_capability_messages.DeviceCapability + ) -> device_capability_messages.DeviceCapability: + """Post-rpc interceptor for get_device_capability + + DEPRECATED. Please use the `post_get_device_capability_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DeviceCapabilityService server but before + it is returned to user code. This `post_get_device_capability` interceptor runs + before the `post_get_device_capability_with_metadata` interceptor. + """ + return response + + def post_get_device_capability_with_metadata( + self, + response: device_capability_messages.DeviceCapability, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + device_capability_messages.DeviceCapability, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for get_device_capability + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DeviceCapabilityService server but before it is returned to user code. + + We recommend only using this `post_get_device_capability_with_metadata` + interceptor in new development instead of the `post_get_device_capability` interceptor. + When both interceptors are used, this `post_get_device_capability_with_metadata` interceptor runs after the + `post_get_device_capability` interceptor. The (possibly modified) response returned by + `post_get_device_capability` will be passed to + `post_get_device_capability_with_metadata`. + """ + return response, metadata + + def pre_list_device_capabilities( + self, + request: device_capability_service.ListDeviceCapabilitiesRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + device_capability_service.ListDeviceCapabilitiesRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for list_device_capabilities + + Override in a subclass to manipulate the request or metadata + before they are sent to the DeviceCapabilityService server. + """ + return request, metadata + + def post_list_device_capabilities( + self, response: device_capability_service.ListDeviceCapabilitiesResponse + ) -> device_capability_service.ListDeviceCapabilitiesResponse: + """Post-rpc interceptor for list_device_capabilities + + DEPRECATED. Please use the `post_list_device_capabilities_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DeviceCapabilityService server but before + it is returned to user code. This `post_list_device_capabilities` interceptor runs + before the `post_list_device_capabilities_with_metadata` interceptor. + """ + return response + + def post_list_device_capabilities_with_metadata( + self, + response: device_capability_service.ListDeviceCapabilitiesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + device_capability_service.ListDeviceCapabilitiesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_device_capabilities + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DeviceCapabilityService server but before it is returned to user code. + + We recommend only using this `post_list_device_capabilities_with_metadata` + interceptor in new development instead of the `post_list_device_capabilities` interceptor. + When both interceptors are used, this `post_list_device_capabilities_with_metadata` interceptor runs after the + `post_list_device_capabilities` interceptor. The (possibly modified) response returned by + `post_list_device_capabilities` will be passed to + `post_list_device_capabilities_with_metadata`. + """ + return response, metadata + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the DeviceCapabilityService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the DeviceCapabilityService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class DeviceCapabilityServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: DeviceCapabilityServiceRestInterceptor + + +class DeviceCapabilityServiceRestTransport(_BaseDeviceCapabilityServiceRestTransport): + """REST backend synchronous transport for DeviceCapabilityService. + + Provides methods for handling ``DeviceCapability`` objects. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[DeviceCapabilityServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or DeviceCapabilityServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _GetDeviceCapability( + _BaseDeviceCapabilityServiceRestTransport._BaseGetDeviceCapability, + DeviceCapabilityServiceRestStub, + ): + def __hash__(self): + return hash("DeviceCapabilityServiceRestTransport.GetDeviceCapability") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: device_capability_service.GetDeviceCapabilityRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> device_capability_messages.DeviceCapability: + r"""Call the get device capability method over HTTP. + + Args: + request (~.device_capability_service.GetDeviceCapabilityRequest): + The request object. Request object for ``GetDeviceCapability`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.device_capability_messages.DeviceCapability: + Represents a device capability. + """ + + http_options = ( + _BaseDeviceCapabilityServiceRestTransport._BaseGetDeviceCapability._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_device_capability( + request, metadata + ) + transcoded_request = _BaseDeviceCapabilityServiceRestTransport._BaseGetDeviceCapability._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseDeviceCapabilityServiceRestTransport._BaseGetDeviceCapability._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.DeviceCapabilityServiceClient.GetDeviceCapability", + extra={ + "serviceName": "google.ads.admanager.v1.DeviceCapabilityService", + "rpcName": "GetDeviceCapability", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + DeviceCapabilityServiceRestTransport._GetDeviceCapability._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = device_capability_messages.DeviceCapability() + pb_resp = device_capability_messages.DeviceCapability.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_device_capability(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_device_capability_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + device_capability_messages.DeviceCapability.to_json(response) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.DeviceCapabilityServiceClient.get_device_capability", + extra={ + "serviceName": "google.ads.admanager.v1.DeviceCapabilityService", + "rpcName": "GetDeviceCapability", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListDeviceCapabilities( + _BaseDeviceCapabilityServiceRestTransport._BaseListDeviceCapabilities, + DeviceCapabilityServiceRestStub, + ): + def __hash__(self): + return hash("DeviceCapabilityServiceRestTransport.ListDeviceCapabilities") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: device_capability_service.ListDeviceCapabilitiesRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> device_capability_service.ListDeviceCapabilitiesResponse: + r"""Call the list device capabilities method over HTTP. + + Args: + request (~.device_capability_service.ListDeviceCapabilitiesRequest): + The request object. Request object for ``ListDeviceCapabilities`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.device_capability_service.ListDeviceCapabilitiesResponse: + Response object for ``ListDeviceCapabilitiesRequest`` + containing matching ``DeviceCapability`` objects. + + """ + + http_options = ( + _BaseDeviceCapabilityServiceRestTransport._BaseListDeviceCapabilities._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_device_capabilities( + request, metadata + ) + transcoded_request = _BaseDeviceCapabilityServiceRestTransport._BaseListDeviceCapabilities._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseDeviceCapabilityServiceRestTransport._BaseListDeviceCapabilities._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.DeviceCapabilityServiceClient.ListDeviceCapabilities", + extra={ + "serviceName": "google.ads.admanager.v1.DeviceCapabilityService", + "rpcName": "ListDeviceCapabilities", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = DeviceCapabilityServiceRestTransport._ListDeviceCapabilities._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = device_capability_service.ListDeviceCapabilitiesResponse() + pb_resp = device_capability_service.ListDeviceCapabilitiesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_device_capabilities(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_device_capabilities_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = device_capability_service.ListDeviceCapabilitiesResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.DeviceCapabilityServiceClient.list_device_capabilities", + extra={ + "serviceName": "google.ads.admanager.v1.DeviceCapabilityService", + "rpcName": "ListDeviceCapabilities", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def get_device_capability( + self, + ) -> Callable[ + [device_capability_service.GetDeviceCapabilityRequest], + device_capability_messages.DeviceCapability, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetDeviceCapability(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_device_capabilities( + self, + ) -> Callable[ + [device_capability_service.ListDeviceCapabilitiesRequest], + device_capability_service.ListDeviceCapabilitiesResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListDeviceCapabilities(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseDeviceCapabilityServiceRestTransport._BaseGetOperation, + DeviceCapabilityServiceRestStub, + ): + def __hash__(self): + return hash("DeviceCapabilityServiceRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = ( + _BaseDeviceCapabilityServiceRestTransport._BaseGetOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = _BaseDeviceCapabilityServiceRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseDeviceCapabilityServiceRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.DeviceCapabilityServiceClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.DeviceCapabilityService", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = DeviceCapabilityServiceRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.DeviceCapabilityServiceAsyncClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.DeviceCapabilityService", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("DeviceCapabilityServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/transports/rest_base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/transports/rest_base.py new file mode 100644 index 000000000000..3c7ad8fe9583 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_capability_service/transports/rest_base.py @@ -0,0 +1,218 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.ads.admanager_v1.types import ( + device_capability_messages, + device_capability_service, +) + +from .base import DEFAULT_CLIENT_INFO, DeviceCapabilityServiceTransport + + +class _BaseDeviceCapabilityServiceRestTransport(DeviceCapabilityServiceTransport): + """Base REST backend transport for DeviceCapabilityService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetDeviceCapability: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/deviceCapabilities/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = device_capability_service.GetDeviceCapabilityRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDeviceCapabilityServiceRestTransport._BaseGetDeviceCapability._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListDeviceCapabilities: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=networks/*}/deviceCapabilities", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = device_capability_service.ListDeviceCapabilitiesRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDeviceCapabilityServiceRestTransport._BaseListDeviceCapabilities._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/operations/reports/runs/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseDeviceCapabilityServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/__init__.py new file mode 100644 index 000000000000..35fcb891b5bf --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 DeviceManufacturerServiceClient + +__all__ = ("DeviceManufacturerServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/client.py new file mode 100644 index 000000000000..a7d41d96e30c --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/client.py @@ -0,0 +1,1058 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +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.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version + +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.longrunning import operations_pb2 # type: ignore + +from google.ads.admanager_v1.services.device_manufacturer_service import pagers +from google.ads.admanager_v1.types import ( + device_manufacturer_messages, + device_manufacturer_service, +) + +from .transports.base import DEFAULT_CLIENT_INFO, DeviceManufacturerServiceTransport +from .transports.rest import DeviceManufacturerServiceRestTransport + + +class DeviceManufacturerServiceClientMeta(type): + """Metaclass for the DeviceManufacturerService 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[DeviceManufacturerServiceTransport]] + _transport_registry["rest"] = DeviceManufacturerServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[DeviceManufacturerServiceTransport]: + """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 DeviceManufacturerServiceClient(metaclass=DeviceManufacturerServiceClientMeta): + """Provides methods for handling ``DeviceManufacturer`` objects.""" + + @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 = "admanager.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "admanager.{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: + DeviceManufacturerServiceClient: 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: + DeviceManufacturerServiceClient: 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) -> DeviceManufacturerServiceTransport: + """Returns the transport used by the client instance. + + Returns: + DeviceManufacturerServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def device_manufacturer_path( + network_code: str, + device_manufacturer: str, + ) -> str: + """Returns a fully-qualified device_manufacturer string.""" + return ( + "networks/{network_code}/deviceManufacturers/{device_manufacturer}".format( + network_code=network_code, + device_manufacturer=device_manufacturer, + ) + ) + + @staticmethod + def parse_device_manufacturer_path(path: str) -> Dict[str, str]: + """Parses a device_manufacturer path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/deviceManufacturers/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def network_path( + network_code: str, + ) -> str: + """Returns a fully-qualified network string.""" + return "networks/{network_code}".format( + network_code=network_code, + ) + + @staticmethod + def parse_network_path(path: str) -> Dict[str, str]: + """Parses a network path into its component segments.""" + m = re.match(r"^networks/(?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 = DeviceManufacturerServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = DeviceManufacturerServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + DeviceManufacturerServiceClient._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 = DeviceManufacturerServiceClient._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, + DeviceManufacturerServiceTransport, + Callable[..., DeviceManufacturerServiceTransport], + ] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the device manufacturer 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,DeviceManufacturerServiceTransport,Callable[..., DeviceManufacturerServiceTransport]]]): + 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 DeviceManufacturerServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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, + ) = DeviceManufacturerServiceClient._read_environment_variables() + self._client_cert_source = ( + DeviceManufacturerServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = DeviceManufacturerServiceClient._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, DeviceManufacturerServiceTransport) + if transport_provided: + # transport is a DeviceManufacturerServiceTransport 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(DeviceManufacturerServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or DeviceManufacturerServiceClient._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[DeviceManufacturerServiceTransport], + Callable[..., DeviceManufacturerServiceTransport], + ] = ( + DeviceManufacturerServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., DeviceManufacturerServiceTransport], 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.admanager_v1.DeviceManufacturerServiceClient`.", + extra={ + "serviceName": "google.ads.admanager.v1.DeviceManufacturerService", + "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.admanager.v1.DeviceManufacturerService", + "credentialsType": None, + }, + ) + + def get_device_manufacturer( + self, + request: Optional[ + Union[device_manufacturer_service.GetDeviceManufacturerRequest, dict] + ] = None, + *, + 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]]] = (), + ) -> device_manufacturer_messages.DeviceManufacturer: + r"""API to retrieve a ``DeviceManufacturer`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_get_device_manufacturer(): + # Create a client + client = admanager_v1.DeviceManufacturerServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetDeviceManufacturerRequest( + name="name_value", + ) + + # Make the request + response = client.get_device_manufacturer(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.GetDeviceManufacturerRequest, dict]): + The request object. Request object for ``GetDeviceManufacturer`` method. + name (str): + Required. The resource name of the DeviceManufacturer. + Format: + ``networks/{network_code}/deviceManufacturers/{device_manufacturer_id}`` + + This corresponds to the ``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.admanager_v1.types.DeviceManufacturer: + Represents a device manufacturer. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, device_manufacturer_service.GetDeviceManufacturerRequest + ): + request = device_manufacturer_service.GetDeviceManufacturerRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_device_manufacturer] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_device_manufacturers( + self, + request: Optional[ + Union[device_manufacturer_service.ListDeviceManufacturersRequest, dict] + ] = None, + *, + parent: 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.ListDeviceManufacturersPager: + r"""API to retrieve a list of ``DeviceManufacturer`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_list_device_manufacturers(): + # Create a client + client = admanager_v1.DeviceManufacturerServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListDeviceManufacturersRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_device_manufacturers(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.ListDeviceManufacturersRequest, dict]): + The request object. Request object for ``ListDeviceManufacturers`` method. + parent (str): + Required. The parent, which owns this collection of + DeviceManufacturers. Format: ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.services.device_manufacturer_service.pagers.ListDeviceManufacturersPager: + Response object for ListDeviceManufacturersRequest containing matching + DeviceManufacturer objects. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, device_manufacturer_service.ListDeviceManufacturersRequest + ): + request = device_manufacturer_service.ListDeviceManufacturersRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_device_manufacturers + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.ListDeviceManufacturersPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "DeviceManufacturerServiceClient": + 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() + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("DeviceManufacturerServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/pagers.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/pagers.py new file mode 100644 index 000000000000..8350962d8ec0 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/pagers.py @@ -0,0 +1,126 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +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 + +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.admanager_v1.types import ( + device_manufacturer_messages, + device_manufacturer_service, +) + + +class ListDeviceManufacturersPager: + """A pager for iterating through ``list_device_manufacturers`` requests. + + This class thinly wraps an initial + :class:`google.ads.admanager_v1.types.ListDeviceManufacturersResponse` object, and + provides an ``__iter__`` method to iterate through its + ``device_manufacturers`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListDeviceManufacturers`` requests and continue to iterate + through the ``device_manufacturers`` field on the + corresponding responses. + + All the usual :class:`google.ads.admanager_v1.types.ListDeviceManufacturersResponse` + 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[ + ..., device_manufacturer_service.ListDeviceManufacturersResponse + ], + request: device_manufacturer_service.ListDeviceManufacturersRequest, + response: device_manufacturer_service.ListDeviceManufacturersResponse, + *, + 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.admanager_v1.types.ListDeviceManufacturersRequest): + The initial request object. + response (google.ads.admanager_v1.types.ListDeviceManufacturersResponse): + 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 = device_manufacturer_service.ListDeviceManufacturersRequest( + 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[device_manufacturer_service.ListDeviceManufacturersResponse]: + 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[device_manufacturer_messages.DeviceManufacturer]: + for page in self.pages: + yield from page.device_manufacturers + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/transports/README.rst b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/transports/README.rst new file mode 100644 index 000000000000..af021612bbfb --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`DeviceManufacturerServiceTransport` is the ABC for all transports. +- public child `DeviceManufacturerServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `DeviceManufacturerServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseDeviceManufacturerServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `DeviceManufacturerServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/transports/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/transports/__init__.py new file mode 100644 index 000000000000..de35fae566fd --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/transports/__init__.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 typing import Dict, Type + +from .base import DeviceManufacturerServiceTransport +from .rest import ( + DeviceManufacturerServiceRestInterceptor, + DeviceManufacturerServiceRestTransport, +) + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[DeviceManufacturerServiceTransport]] +_transport_registry["rest"] = DeviceManufacturerServiceRestTransport + +__all__ = ( + "DeviceManufacturerServiceTransport", + "DeviceManufacturerServiceRestTransport", + "DeviceManufacturerServiceRestInterceptor", +) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/transports/base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/transports/base.py new file mode 100644 index 000000000000..196acee618c3 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/transports/base.py @@ -0,0 +1,204 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version +from google.ads.admanager_v1.types import ( + device_manufacturer_messages, + device_manufacturer_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 DeviceManufacturerServiceTransport(abc.ABC): + """Abstract transport class for DeviceManufacturerService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/admanager",) + + DEFAULT_HOST: str = "admanager.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: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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_device_manufacturer: gapic_v1.method.wrap_method( + self.get_device_manufacturer, + default_timeout=None, + client_info=client_info, + ), + self.list_device_manufacturers: gapic_v1.method.wrap_method( + self.list_device_manufacturers, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + 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_device_manufacturer( + self, + ) -> Callable[ + [device_manufacturer_service.GetDeviceManufacturerRequest], + Union[ + device_manufacturer_messages.DeviceManufacturer, + Awaitable[device_manufacturer_messages.DeviceManufacturer], + ], + ]: + raise NotImplementedError() + + @property + def list_device_manufacturers( + self, + ) -> Callable[ + [device_manufacturer_service.ListDeviceManufacturersRequest], + Union[ + device_manufacturer_service.ListDeviceManufacturersResponse, + Awaitable[device_manufacturer_service.ListDeviceManufacturersResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("DeviceManufacturerServiceTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/transports/rest.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/transports/rest.py new file mode 100644 index 000000000000..825c4cd4522d --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/transports/rest.py @@ -0,0 +1,799 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.ads.admanager_v1.types import ( + device_manufacturer_messages, + device_manufacturer_service, +) + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseDeviceManufacturerServiceRestTransport + +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 = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class DeviceManufacturerServiceRestInterceptor: + """Interceptor for DeviceManufacturerService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the DeviceManufacturerServiceRestTransport. + + .. code-block:: python + class MyCustomDeviceManufacturerServiceInterceptor(DeviceManufacturerServiceRestInterceptor): + def pre_get_device_manufacturer(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_device_manufacturer(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_device_manufacturers(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_device_manufacturers(self, response): + logging.log(f"Received response: {response}") + return response + + transport = DeviceManufacturerServiceRestTransport(interceptor=MyCustomDeviceManufacturerServiceInterceptor()) + client = DeviceManufacturerServiceClient(transport=transport) + + + """ + + def pre_get_device_manufacturer( + self, + request: device_manufacturer_service.GetDeviceManufacturerRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + device_manufacturer_service.GetDeviceManufacturerRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for get_device_manufacturer + + Override in a subclass to manipulate the request or metadata + before they are sent to the DeviceManufacturerService server. + """ + return request, metadata + + def post_get_device_manufacturer( + self, response: device_manufacturer_messages.DeviceManufacturer + ) -> device_manufacturer_messages.DeviceManufacturer: + """Post-rpc interceptor for get_device_manufacturer + + DEPRECATED. Please use the `post_get_device_manufacturer_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DeviceManufacturerService server but before + it is returned to user code. This `post_get_device_manufacturer` interceptor runs + before the `post_get_device_manufacturer_with_metadata` interceptor. + """ + return response + + def post_get_device_manufacturer_with_metadata( + self, + response: device_manufacturer_messages.DeviceManufacturer, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + device_manufacturer_messages.DeviceManufacturer, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for get_device_manufacturer + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DeviceManufacturerService server but before it is returned to user code. + + We recommend only using this `post_get_device_manufacturer_with_metadata` + interceptor in new development instead of the `post_get_device_manufacturer` interceptor. + When both interceptors are used, this `post_get_device_manufacturer_with_metadata` interceptor runs after the + `post_get_device_manufacturer` interceptor. The (possibly modified) response returned by + `post_get_device_manufacturer` will be passed to + `post_get_device_manufacturer_with_metadata`. + """ + return response, metadata + + def pre_list_device_manufacturers( + self, + request: device_manufacturer_service.ListDeviceManufacturersRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + device_manufacturer_service.ListDeviceManufacturersRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for list_device_manufacturers + + Override in a subclass to manipulate the request or metadata + before they are sent to the DeviceManufacturerService server. + """ + return request, metadata + + def post_list_device_manufacturers( + self, response: device_manufacturer_service.ListDeviceManufacturersResponse + ) -> device_manufacturer_service.ListDeviceManufacturersResponse: + """Post-rpc interceptor for list_device_manufacturers + + DEPRECATED. Please use the `post_list_device_manufacturers_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the DeviceManufacturerService server but before + it is returned to user code. This `post_list_device_manufacturers` interceptor runs + before the `post_list_device_manufacturers_with_metadata` interceptor. + """ + return response + + def post_list_device_manufacturers_with_metadata( + self, + response: device_manufacturer_service.ListDeviceManufacturersResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + device_manufacturer_service.ListDeviceManufacturersResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_device_manufacturers + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DeviceManufacturerService server but before it is returned to user code. + + We recommend only using this `post_list_device_manufacturers_with_metadata` + interceptor in new development instead of the `post_list_device_manufacturers` interceptor. + When both interceptors are used, this `post_list_device_manufacturers_with_metadata` interceptor runs after the + `post_list_device_manufacturers` interceptor. The (possibly modified) response returned by + `post_list_device_manufacturers` will be passed to + `post_list_device_manufacturers_with_metadata`. + """ + return response, metadata + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the DeviceManufacturerService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the DeviceManufacturerService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class DeviceManufacturerServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: DeviceManufacturerServiceRestInterceptor + + +class DeviceManufacturerServiceRestTransport( + _BaseDeviceManufacturerServiceRestTransport +): + """REST backend synchronous transport for DeviceManufacturerService. + + Provides methods for handling ``DeviceManufacturer`` objects. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[DeviceManufacturerServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or DeviceManufacturerServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _GetDeviceManufacturer( + _BaseDeviceManufacturerServiceRestTransport._BaseGetDeviceManufacturer, + DeviceManufacturerServiceRestStub, + ): + def __hash__(self): + return hash("DeviceManufacturerServiceRestTransport.GetDeviceManufacturer") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: device_manufacturer_service.GetDeviceManufacturerRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> device_manufacturer_messages.DeviceManufacturer: + r"""Call the get device manufacturer method over HTTP. + + Args: + request (~.device_manufacturer_service.GetDeviceManufacturerRequest): + The request object. Request object for ``GetDeviceManufacturer`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.device_manufacturer_messages.DeviceManufacturer: + Represents a device manufacturer. + """ + + http_options = ( + _BaseDeviceManufacturerServiceRestTransport._BaseGetDeviceManufacturer._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_device_manufacturer( + request, metadata + ) + transcoded_request = _BaseDeviceManufacturerServiceRestTransport._BaseGetDeviceManufacturer._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseDeviceManufacturerServiceRestTransport._BaseGetDeviceManufacturer._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.DeviceManufacturerServiceClient.GetDeviceManufacturer", + extra={ + "serviceName": "google.ads.admanager.v1.DeviceManufacturerService", + "rpcName": "GetDeviceManufacturer", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = DeviceManufacturerServiceRestTransport._GetDeviceManufacturer._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = device_manufacturer_messages.DeviceManufacturer() + pb_resp = device_manufacturer_messages.DeviceManufacturer.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_device_manufacturer(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_device_manufacturer_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + device_manufacturer_messages.DeviceManufacturer.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.DeviceManufacturerServiceClient.get_device_manufacturer", + extra={ + "serviceName": "google.ads.admanager.v1.DeviceManufacturerService", + "rpcName": "GetDeviceManufacturer", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListDeviceManufacturers( + _BaseDeviceManufacturerServiceRestTransport._BaseListDeviceManufacturers, + DeviceManufacturerServiceRestStub, + ): + def __hash__(self): + return hash( + "DeviceManufacturerServiceRestTransport.ListDeviceManufacturers" + ) + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: device_manufacturer_service.ListDeviceManufacturersRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> device_manufacturer_service.ListDeviceManufacturersResponse: + r"""Call the list device manufacturers method over HTTP. + + Args: + request (~.device_manufacturer_service.ListDeviceManufacturersRequest): + The request object. Request object for ``ListDeviceManufacturers`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.device_manufacturer_service.ListDeviceManufacturersResponse: + Response object for ``ListDeviceManufacturersRequest`` + containing matching ``DeviceManufacturer`` objects. + + """ + + http_options = ( + _BaseDeviceManufacturerServiceRestTransport._BaseListDeviceManufacturers._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_device_manufacturers( + request, metadata + ) + transcoded_request = _BaseDeviceManufacturerServiceRestTransport._BaseListDeviceManufacturers._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseDeviceManufacturerServiceRestTransport._BaseListDeviceManufacturers._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.DeviceManufacturerServiceClient.ListDeviceManufacturers", + extra={ + "serviceName": "google.ads.admanager.v1.DeviceManufacturerService", + "rpcName": "ListDeviceManufacturers", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = DeviceManufacturerServiceRestTransport._ListDeviceManufacturers._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = device_manufacturer_service.ListDeviceManufacturersResponse() + pb_resp = device_manufacturer_service.ListDeviceManufacturersResponse.pb( + resp + ) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_device_manufacturers(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_device_manufacturers_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = device_manufacturer_service.ListDeviceManufacturersResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.DeviceManufacturerServiceClient.list_device_manufacturers", + extra={ + "serviceName": "google.ads.admanager.v1.DeviceManufacturerService", + "rpcName": "ListDeviceManufacturers", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def get_device_manufacturer( + self, + ) -> Callable[ + [device_manufacturer_service.GetDeviceManufacturerRequest], + device_manufacturer_messages.DeviceManufacturer, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetDeviceManufacturer(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_device_manufacturers( + self, + ) -> Callable[ + [device_manufacturer_service.ListDeviceManufacturersRequest], + device_manufacturer_service.ListDeviceManufacturersResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListDeviceManufacturers(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseDeviceManufacturerServiceRestTransport._BaseGetOperation, + DeviceManufacturerServiceRestStub, + ): + def __hash__(self): + return hash("DeviceManufacturerServiceRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = ( + _BaseDeviceManufacturerServiceRestTransport._BaseGetOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = _BaseDeviceManufacturerServiceRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseDeviceManufacturerServiceRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.DeviceManufacturerServiceClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.DeviceManufacturerService", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + DeviceManufacturerServiceRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.DeviceManufacturerServiceAsyncClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.DeviceManufacturerService", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("DeviceManufacturerServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/transports/rest_base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/transports/rest_base.py new file mode 100644 index 000000000000..1c431e56d37a --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/device_manufacturer_service/transports/rest_base.py @@ -0,0 +1,218 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.ads.admanager_v1.types import ( + device_manufacturer_messages, + device_manufacturer_service, +) + +from .base import DEFAULT_CLIENT_INFO, DeviceManufacturerServiceTransport + + +class _BaseDeviceManufacturerServiceRestTransport(DeviceManufacturerServiceTransport): + """Base REST backend transport for DeviceManufacturerService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetDeviceManufacturer: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/deviceManufacturers/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = device_manufacturer_service.GetDeviceManufacturerRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDeviceManufacturerServiceRestTransport._BaseGetDeviceManufacturer._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListDeviceManufacturers: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=networks/*}/deviceManufacturers", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = device_manufacturer_service.ListDeviceManufacturersRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseDeviceManufacturerServiceRestTransport._BaseListDeviceManufacturers._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/operations/reports/runs/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseDeviceManufacturerServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/__init__.py new file mode 100644 index 000000000000..f70fdc9a3406 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MobileCarrierServiceClient + +__all__ = ("MobileCarrierServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/client.py new file mode 100644 index 000000000000..efbcbcd0e152 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/client.py @@ -0,0 +1,1044 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +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.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version + +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.longrunning import operations_pb2 # type: ignore + +from google.ads.admanager_v1.services.mobile_carrier_service import pagers +from google.ads.admanager_v1.types import ( + mobile_carrier_messages, + mobile_carrier_service, +) + +from .transports.base import DEFAULT_CLIENT_INFO, MobileCarrierServiceTransport +from .transports.rest import MobileCarrierServiceRestTransport + + +class MobileCarrierServiceClientMeta(type): + """Metaclass for the MobileCarrierService 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[MobileCarrierServiceTransport]] + _transport_registry["rest"] = MobileCarrierServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[MobileCarrierServiceTransport]: + """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 MobileCarrierServiceClient(metaclass=MobileCarrierServiceClientMeta): + """Provides methods for handling ``MobileCarrier`` objects.""" + + @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 = "admanager.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "admanager.{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: + MobileCarrierServiceClient: 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: + MobileCarrierServiceClient: 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) -> MobileCarrierServiceTransport: + """Returns the transport used by the client instance. + + Returns: + MobileCarrierServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def mobile_carrier_path( + network_code: str, + mobile_carrier: str, + ) -> str: + """Returns a fully-qualified mobile_carrier string.""" + return "networks/{network_code}/mobileCarriers/{mobile_carrier}".format( + network_code=network_code, + mobile_carrier=mobile_carrier, + ) + + @staticmethod + def parse_mobile_carrier_path(path: str) -> Dict[str, str]: + """Parses a mobile_carrier path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/mobileCarriers/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def network_path( + network_code: str, + ) -> str: + """Returns a fully-qualified network string.""" + return "networks/{network_code}".format( + network_code=network_code, + ) + + @staticmethod + def parse_network_path(path: str) -> Dict[str, str]: + """Parses a network path into its component segments.""" + m = re.match(r"^networks/(?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 = MobileCarrierServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = MobileCarrierServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = MobileCarrierServiceClient._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 = MobileCarrierServiceClient._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, + MobileCarrierServiceTransport, + Callable[..., MobileCarrierServiceTransport], + ] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the mobile carrier 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,MobileCarrierServiceTransport,Callable[..., MobileCarrierServiceTransport]]]): + 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 MobileCarrierServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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, + ) = MobileCarrierServiceClient._read_environment_variables() + self._client_cert_source = MobileCarrierServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = MobileCarrierServiceClient._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, MobileCarrierServiceTransport) + if transport_provided: + # transport is a MobileCarrierServiceTransport 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(MobileCarrierServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or MobileCarrierServiceClient._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[MobileCarrierServiceTransport], + Callable[..., MobileCarrierServiceTransport], + ] = ( + MobileCarrierServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., MobileCarrierServiceTransport], 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.admanager_v1.MobileCarrierServiceClient`.", + extra={ + "serviceName": "google.ads.admanager.v1.MobileCarrierService", + "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.admanager.v1.MobileCarrierService", + "credentialsType": None, + }, + ) + + def get_mobile_carrier( + self, + request: Optional[ + Union[mobile_carrier_service.GetMobileCarrierRequest, dict] + ] = None, + *, + 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]]] = (), + ) -> mobile_carrier_messages.MobileCarrier: + r"""API to retrieve a ``MobileCarrier`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_get_mobile_carrier(): + # Create a client + client = admanager_v1.MobileCarrierServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetMobileCarrierRequest( + name="name_value", + ) + + # Make the request + response = client.get_mobile_carrier(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.GetMobileCarrierRequest, dict]): + The request object. Request object for ``GetMobileCarrier`` method. + name (str): + Required. The resource name of the MobileCarrier. + Format: + ``networks/{network_code}/mobileCarriers/{mobile_carrier_id}`` + + This corresponds to the ``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.admanager_v1.types.MobileCarrier: + Represents a mobile carrier. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, mobile_carrier_service.GetMobileCarrierRequest): + request = mobile_carrier_service.GetMobileCarrierRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_mobile_carrier] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_mobile_carriers( + self, + request: Optional[ + Union[mobile_carrier_service.ListMobileCarriersRequest, dict] + ] = None, + *, + parent: 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.ListMobileCarriersPager: + r"""API to retrieve a list of ``MobileCarrier`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_list_mobile_carriers(): + # Create a client + client = admanager_v1.MobileCarrierServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListMobileCarriersRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_mobile_carriers(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.ListMobileCarriersRequest, dict]): + The request object. Request object for ``ListMobileCarriers`` method. + parent (str): + Required. The parent, which owns this collection of + MobileCarriers. Format: ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.services.mobile_carrier_service.pagers.ListMobileCarriersPager: + Response object for ListMobileCarriersRequest containing matching + MobileCarrier objects. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, mobile_carrier_service.ListMobileCarriersRequest): + request = mobile_carrier_service.ListMobileCarriersRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_mobile_carriers] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.ListMobileCarriersPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "MobileCarrierServiceClient": + 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() + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("MobileCarrierServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/pagers.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/pagers.py new file mode 100644 index 000000000000..1e2c65ccb757 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/pagers.py @@ -0,0 +1,120 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +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 + +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.admanager_v1.types import ( + mobile_carrier_messages, + mobile_carrier_service, +) + + +class ListMobileCarriersPager: + """A pager for iterating through ``list_mobile_carriers`` requests. + + This class thinly wraps an initial + :class:`google.ads.admanager_v1.types.ListMobileCarriersResponse` object, and + provides an ``__iter__`` method to iterate through its + ``mobile_carriers`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListMobileCarriers`` requests and continue to iterate + through the ``mobile_carriers`` field on the + corresponding responses. + + All the usual :class:`google.ads.admanager_v1.types.ListMobileCarriersResponse` + 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[..., mobile_carrier_service.ListMobileCarriersResponse], + request: mobile_carrier_service.ListMobileCarriersRequest, + response: mobile_carrier_service.ListMobileCarriersResponse, + *, + 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.admanager_v1.types.ListMobileCarriersRequest): + The initial request object. + response (google.ads.admanager_v1.types.ListMobileCarriersResponse): + 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 = mobile_carrier_service.ListMobileCarriersRequest(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[mobile_carrier_service.ListMobileCarriersResponse]: + 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[mobile_carrier_messages.MobileCarrier]: + for page in self.pages: + yield from page.mobile_carriers + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/transports/README.rst b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/transports/README.rst new file mode 100644 index 000000000000..2095ecbf7d0e --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`MobileCarrierServiceTransport` is the ABC for all transports. +- public child `MobileCarrierServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `MobileCarrierServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseMobileCarrierServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `MobileCarrierServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/transports/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/transports/__init__.py new file mode 100644 index 000000000000..544e6e3e623d --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/transports/__init__.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 typing import Dict, Type + +from .base import MobileCarrierServiceTransport +from .rest import MobileCarrierServiceRestInterceptor, MobileCarrierServiceRestTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[MobileCarrierServiceTransport]] +_transport_registry["rest"] = MobileCarrierServiceRestTransport + +__all__ = ( + "MobileCarrierServiceTransport", + "MobileCarrierServiceRestTransport", + "MobileCarrierServiceRestInterceptor", +) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/transports/base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/transports/base.py new file mode 100644 index 000000000000..4065fa144ce6 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/transports/base.py @@ -0,0 +1,204 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version +from google.ads.admanager_v1.types import ( + mobile_carrier_messages, + mobile_carrier_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 MobileCarrierServiceTransport(abc.ABC): + """Abstract transport class for MobileCarrierService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/admanager",) + + DEFAULT_HOST: str = "admanager.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: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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_mobile_carrier: gapic_v1.method.wrap_method( + self.get_mobile_carrier, + default_timeout=None, + client_info=client_info, + ), + self.list_mobile_carriers: gapic_v1.method.wrap_method( + self.list_mobile_carriers, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + 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_mobile_carrier( + self, + ) -> Callable[ + [mobile_carrier_service.GetMobileCarrierRequest], + Union[ + mobile_carrier_messages.MobileCarrier, + Awaitable[mobile_carrier_messages.MobileCarrier], + ], + ]: + raise NotImplementedError() + + @property + def list_mobile_carriers( + self, + ) -> Callable[ + [mobile_carrier_service.ListMobileCarriersRequest], + Union[ + mobile_carrier_service.ListMobileCarriersResponse, + Awaitable[mobile_carrier_service.ListMobileCarriersResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("MobileCarrierServiceTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/transports/rest.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/transports/rest.py new file mode 100644 index 000000000000..47e7bd49560f --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/transports/rest.py @@ -0,0 +1,794 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.ads.admanager_v1.types import ( + mobile_carrier_messages, + mobile_carrier_service, +) + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseMobileCarrierServiceRestTransport + +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 = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class MobileCarrierServiceRestInterceptor: + """Interceptor for MobileCarrierService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the MobileCarrierServiceRestTransport. + + .. code-block:: python + class MyCustomMobileCarrierServiceInterceptor(MobileCarrierServiceRestInterceptor): + def pre_get_mobile_carrier(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_mobile_carrier(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_mobile_carriers(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_mobile_carriers(self, response): + logging.log(f"Received response: {response}") + return response + + transport = MobileCarrierServiceRestTransport(interceptor=MyCustomMobileCarrierServiceInterceptor()) + client = MobileCarrierServiceClient(transport=transport) + + + """ + + def pre_get_mobile_carrier( + self, + request: mobile_carrier_service.GetMobileCarrierRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + mobile_carrier_service.GetMobileCarrierRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for get_mobile_carrier + + Override in a subclass to manipulate the request or metadata + before they are sent to the MobileCarrierService server. + """ + return request, metadata + + def post_get_mobile_carrier( + self, response: mobile_carrier_messages.MobileCarrier + ) -> mobile_carrier_messages.MobileCarrier: + """Post-rpc interceptor for get_mobile_carrier + + DEPRECATED. Please use the `post_get_mobile_carrier_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the MobileCarrierService server but before + it is returned to user code. This `post_get_mobile_carrier` interceptor runs + before the `post_get_mobile_carrier_with_metadata` interceptor. + """ + return response + + def post_get_mobile_carrier_with_metadata( + self, + response: mobile_carrier_messages.MobileCarrier, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + mobile_carrier_messages.MobileCarrier, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_mobile_carrier + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the MobileCarrierService server but before it is returned to user code. + + We recommend only using this `post_get_mobile_carrier_with_metadata` + interceptor in new development instead of the `post_get_mobile_carrier` interceptor. + When both interceptors are used, this `post_get_mobile_carrier_with_metadata` interceptor runs after the + `post_get_mobile_carrier` interceptor. The (possibly modified) response returned by + `post_get_mobile_carrier` will be passed to + `post_get_mobile_carrier_with_metadata`. + """ + return response, metadata + + def pre_list_mobile_carriers( + self, + request: mobile_carrier_service.ListMobileCarriersRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + mobile_carrier_service.ListMobileCarriersRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for list_mobile_carriers + + Override in a subclass to manipulate the request or metadata + before they are sent to the MobileCarrierService server. + """ + return request, metadata + + def post_list_mobile_carriers( + self, response: mobile_carrier_service.ListMobileCarriersResponse + ) -> mobile_carrier_service.ListMobileCarriersResponse: + """Post-rpc interceptor for list_mobile_carriers + + DEPRECATED. Please use the `post_list_mobile_carriers_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the MobileCarrierService server but before + it is returned to user code. This `post_list_mobile_carriers` interceptor runs + before the `post_list_mobile_carriers_with_metadata` interceptor. + """ + return response + + def post_list_mobile_carriers_with_metadata( + self, + response: mobile_carrier_service.ListMobileCarriersResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + mobile_carrier_service.ListMobileCarriersResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_mobile_carriers + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the MobileCarrierService server but before it is returned to user code. + + We recommend only using this `post_list_mobile_carriers_with_metadata` + interceptor in new development instead of the `post_list_mobile_carriers` interceptor. + When both interceptors are used, this `post_list_mobile_carriers_with_metadata` interceptor runs after the + `post_list_mobile_carriers` interceptor. The (possibly modified) response returned by + `post_list_mobile_carriers` will be passed to + `post_list_mobile_carriers_with_metadata`. + """ + return response, metadata + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the MobileCarrierService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the MobileCarrierService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class MobileCarrierServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: MobileCarrierServiceRestInterceptor + + +class MobileCarrierServiceRestTransport(_BaseMobileCarrierServiceRestTransport): + """REST backend synchronous transport for MobileCarrierService. + + Provides methods for handling ``MobileCarrier`` objects. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[MobileCarrierServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or MobileCarrierServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _GetMobileCarrier( + _BaseMobileCarrierServiceRestTransport._BaseGetMobileCarrier, + MobileCarrierServiceRestStub, + ): + def __hash__(self): + return hash("MobileCarrierServiceRestTransport.GetMobileCarrier") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: mobile_carrier_service.GetMobileCarrierRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> mobile_carrier_messages.MobileCarrier: + r"""Call the get mobile carrier method over HTTP. + + Args: + request (~.mobile_carrier_service.GetMobileCarrierRequest): + The request object. Request object for ``GetMobileCarrier`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.mobile_carrier_messages.MobileCarrier: + Represents a mobile carrier. + """ + + http_options = ( + _BaseMobileCarrierServiceRestTransport._BaseGetMobileCarrier._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_mobile_carrier( + request, metadata + ) + transcoded_request = _BaseMobileCarrierServiceRestTransport._BaseGetMobileCarrier._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseMobileCarrierServiceRestTransport._BaseGetMobileCarrier._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.MobileCarrierServiceClient.GetMobileCarrier", + extra={ + "serviceName": "google.ads.admanager.v1.MobileCarrierService", + "rpcName": "GetMobileCarrier", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + MobileCarrierServiceRestTransport._GetMobileCarrier._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = mobile_carrier_messages.MobileCarrier() + pb_resp = mobile_carrier_messages.MobileCarrier.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_mobile_carrier(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_mobile_carrier_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = mobile_carrier_messages.MobileCarrier.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.MobileCarrierServiceClient.get_mobile_carrier", + extra={ + "serviceName": "google.ads.admanager.v1.MobileCarrierService", + "rpcName": "GetMobileCarrier", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListMobileCarriers( + _BaseMobileCarrierServiceRestTransport._BaseListMobileCarriers, + MobileCarrierServiceRestStub, + ): + def __hash__(self): + return hash("MobileCarrierServiceRestTransport.ListMobileCarriers") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: mobile_carrier_service.ListMobileCarriersRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> mobile_carrier_service.ListMobileCarriersResponse: + r"""Call the list mobile carriers method over HTTP. + + Args: + request (~.mobile_carrier_service.ListMobileCarriersRequest): + The request object. Request object for ``ListMobileCarriers`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.mobile_carrier_service.ListMobileCarriersResponse: + Response object for ``ListMobileCarriersRequest`` + containing matching ``MobileCarrier`` objects. + + """ + + http_options = ( + _BaseMobileCarrierServiceRestTransport._BaseListMobileCarriers._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_mobile_carriers( + request, metadata + ) + transcoded_request = _BaseMobileCarrierServiceRestTransport._BaseListMobileCarriers._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseMobileCarrierServiceRestTransport._BaseListMobileCarriers._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.MobileCarrierServiceClient.ListMobileCarriers", + extra={ + "serviceName": "google.ads.admanager.v1.MobileCarrierService", + "rpcName": "ListMobileCarriers", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + MobileCarrierServiceRestTransport._ListMobileCarriers._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = mobile_carrier_service.ListMobileCarriersResponse() + pb_resp = mobile_carrier_service.ListMobileCarriersResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_mobile_carriers(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_mobile_carriers_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + mobile_carrier_service.ListMobileCarriersResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.MobileCarrierServiceClient.list_mobile_carriers", + extra={ + "serviceName": "google.ads.admanager.v1.MobileCarrierService", + "rpcName": "ListMobileCarriers", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def get_mobile_carrier( + self, + ) -> Callable[ + [mobile_carrier_service.GetMobileCarrierRequest], + mobile_carrier_messages.MobileCarrier, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetMobileCarrier(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_mobile_carriers( + self, + ) -> Callable[ + [mobile_carrier_service.ListMobileCarriersRequest], + mobile_carrier_service.ListMobileCarriersResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListMobileCarriers(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseMobileCarrierServiceRestTransport._BaseGetOperation, + MobileCarrierServiceRestStub, + ): + def __hash__(self): + return hash("MobileCarrierServiceRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = ( + _BaseMobileCarrierServiceRestTransport._BaseGetOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = _BaseMobileCarrierServiceRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseMobileCarrierServiceRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.MobileCarrierServiceClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.MobileCarrierService", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = MobileCarrierServiceRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.MobileCarrierServiceAsyncClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.MobileCarrierService", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("MobileCarrierServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/transports/rest_base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/transports/rest_base.py new file mode 100644 index 000000000000..58cce5080306 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_carrier_service/transports/rest_base.py @@ -0,0 +1,214 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.ads.admanager_v1.types import ( + mobile_carrier_messages, + mobile_carrier_service, +) + +from .base import DEFAULT_CLIENT_INFO, MobileCarrierServiceTransport + + +class _BaseMobileCarrierServiceRestTransport(MobileCarrierServiceTransport): + """Base REST backend transport for MobileCarrierService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetMobileCarrier: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/mobileCarriers/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = mobile_carrier_service.GetMobileCarrierRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseMobileCarrierServiceRestTransport._BaseGetMobileCarrier._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListMobileCarriers: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=networks/*}/mobileCarriers", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = mobile_carrier_service.ListMobileCarriersRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseMobileCarrierServiceRestTransport._BaseListMobileCarriers._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/operations/reports/runs/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseMobileCarrierServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/__init__.py new file mode 100644 index 000000000000..12df81efba04 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MobileDeviceServiceClient + +__all__ = ("MobileDeviceServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/client.py new file mode 100644 index 000000000000..1d0abd44b4ec --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/client.py @@ -0,0 +1,1062 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +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.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version + +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.longrunning import operations_pb2 # type: ignore + +from google.ads.admanager_v1.services.mobile_device_service import pagers +from google.ads.admanager_v1.types import mobile_device_messages, mobile_device_service + +from .transports.base import DEFAULT_CLIENT_INFO, MobileDeviceServiceTransport +from .transports.rest import MobileDeviceServiceRestTransport + + +class MobileDeviceServiceClientMeta(type): + """Metaclass for the MobileDeviceService 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[MobileDeviceServiceTransport]] + _transport_registry["rest"] = MobileDeviceServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[MobileDeviceServiceTransport]: + """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 MobileDeviceServiceClient(metaclass=MobileDeviceServiceClientMeta): + """Provides methods for handling ``MobileDevice`` objects.""" + + @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 = "admanager.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "admanager.{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: + MobileDeviceServiceClient: 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: + MobileDeviceServiceClient: 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) -> MobileDeviceServiceTransport: + """Returns the transport used by the client instance. + + Returns: + MobileDeviceServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def device_manufacturer_path( + network_code: str, + device_manufacturer: str, + ) -> str: + """Returns a fully-qualified device_manufacturer string.""" + return ( + "networks/{network_code}/deviceManufacturers/{device_manufacturer}".format( + network_code=network_code, + device_manufacturer=device_manufacturer, + ) + ) + + @staticmethod + def parse_device_manufacturer_path(path: str) -> Dict[str, str]: + """Parses a device_manufacturer path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/deviceManufacturers/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def mobile_device_path( + network_code: str, + mobile_device: str, + ) -> str: + """Returns a fully-qualified mobile_device string.""" + return "networks/{network_code}/mobileDevices/{mobile_device}".format( + network_code=network_code, + mobile_device=mobile_device, + ) + + @staticmethod + def parse_mobile_device_path(path: str) -> Dict[str, str]: + """Parses a mobile_device path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/mobileDevices/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def network_path( + network_code: str, + ) -> str: + """Returns a fully-qualified network string.""" + return "networks/{network_code}".format( + network_code=network_code, + ) + + @staticmethod + def parse_network_path(path: str) -> Dict[str, str]: + """Parses a network path into its component segments.""" + m = re.match(r"^networks/(?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 = MobileDeviceServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = MobileDeviceServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = MobileDeviceServiceClient._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 = MobileDeviceServiceClient._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, + MobileDeviceServiceTransport, + Callable[..., MobileDeviceServiceTransport], + ] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the mobile device 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,MobileDeviceServiceTransport,Callable[..., MobileDeviceServiceTransport]]]): + 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 MobileDeviceServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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, + ) = MobileDeviceServiceClient._read_environment_variables() + self._client_cert_source = MobileDeviceServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = MobileDeviceServiceClient._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, MobileDeviceServiceTransport) + if transport_provided: + # transport is a MobileDeviceServiceTransport 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(MobileDeviceServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or MobileDeviceServiceClient._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[MobileDeviceServiceTransport], + Callable[..., MobileDeviceServiceTransport], + ] = ( + MobileDeviceServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., MobileDeviceServiceTransport], 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.admanager_v1.MobileDeviceServiceClient`.", + extra={ + "serviceName": "google.ads.admanager.v1.MobileDeviceService", + "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.admanager.v1.MobileDeviceService", + "credentialsType": None, + }, + ) + + def get_mobile_device( + self, + request: Optional[ + Union[mobile_device_service.GetMobileDeviceRequest, dict] + ] = None, + *, + 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]]] = (), + ) -> mobile_device_messages.MobileDevice: + r"""API to retrieve a ``MobileDevice`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_get_mobile_device(): + # Create a client + client = admanager_v1.MobileDeviceServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetMobileDeviceRequest( + name="name_value", + ) + + # Make the request + response = client.get_mobile_device(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.GetMobileDeviceRequest, dict]): + The request object. Request object for ``GetMobileDevice`` method. + name (str): + Required. The resource name of the MobileDevice. Format: + ``networks/{network_code}/mobileDevices/{mobile_device_id}`` + + This corresponds to the ``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.admanager_v1.types.MobileDevice: + Represents a mobile device. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, mobile_device_service.GetMobileDeviceRequest): + request = mobile_device_service.GetMobileDeviceRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_mobile_device] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_mobile_devices( + self, + request: Optional[ + Union[mobile_device_service.ListMobileDevicesRequest, dict] + ] = None, + *, + parent: 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.ListMobileDevicesPager: + r"""API to retrieve a list of ``MobileDevice`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_list_mobile_devices(): + # Create a client + client = admanager_v1.MobileDeviceServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListMobileDevicesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_mobile_devices(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.ListMobileDevicesRequest, dict]): + The request object. Request object for ``ListMobileDevices`` method. + parent (str): + Required. The parent, which owns this collection of + MobileDevices. Format: ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.services.mobile_device_service.pagers.ListMobileDevicesPager: + Response object for ListMobileDevicesRequest containing matching + MobileDevice objects. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, mobile_device_service.ListMobileDevicesRequest): + request = mobile_device_service.ListMobileDevicesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_mobile_devices] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.ListMobileDevicesPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "MobileDeviceServiceClient": + 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() + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("MobileDeviceServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/pagers.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/pagers.py new file mode 100644 index 000000000000..ab6a4cfa93ab --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/pagers.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +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 + +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.admanager_v1.types import mobile_device_messages, mobile_device_service + + +class ListMobileDevicesPager: + """A pager for iterating through ``list_mobile_devices`` requests. + + This class thinly wraps an initial + :class:`google.ads.admanager_v1.types.ListMobileDevicesResponse` object, and + provides an ``__iter__`` method to iterate through its + ``mobile_devices`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListMobileDevices`` requests and continue to iterate + through the ``mobile_devices`` field on the + corresponding responses. + + All the usual :class:`google.ads.admanager_v1.types.ListMobileDevicesResponse` + 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[..., mobile_device_service.ListMobileDevicesResponse], + request: mobile_device_service.ListMobileDevicesRequest, + response: mobile_device_service.ListMobileDevicesResponse, + *, + 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.admanager_v1.types.ListMobileDevicesRequest): + The initial request object. + response (google.ads.admanager_v1.types.ListMobileDevicesResponse): + 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 = mobile_device_service.ListMobileDevicesRequest(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[mobile_device_service.ListMobileDevicesResponse]: + 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[mobile_device_messages.MobileDevice]: + for page in self.pages: + yield from page.mobile_devices + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/transports/README.rst b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/transports/README.rst new file mode 100644 index 000000000000..64872238c0aa --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`MobileDeviceServiceTransport` is the ABC for all transports. +- public child `MobileDeviceServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `MobileDeviceServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseMobileDeviceServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `MobileDeviceServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/transports/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/transports/__init__.py new file mode 100644 index 000000000000..b01a56ca24a4 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/transports/__init__.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 typing import Dict, Type + +from .base import MobileDeviceServiceTransport +from .rest import MobileDeviceServiceRestInterceptor, MobileDeviceServiceRestTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[MobileDeviceServiceTransport]] +_transport_registry["rest"] = MobileDeviceServiceRestTransport + +__all__ = ( + "MobileDeviceServiceTransport", + "MobileDeviceServiceRestTransport", + "MobileDeviceServiceRestInterceptor", +) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/transports/base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/transports/base.py new file mode 100644 index 000000000000..3e553289733c --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/transports/base.py @@ -0,0 +1,201 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version +from google.ads.admanager_v1.types import mobile_device_messages, mobile_device_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 MobileDeviceServiceTransport(abc.ABC): + """Abstract transport class for MobileDeviceService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/admanager",) + + DEFAULT_HOST: str = "admanager.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: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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_mobile_device: gapic_v1.method.wrap_method( + self.get_mobile_device, + default_timeout=None, + client_info=client_info, + ), + self.list_mobile_devices: gapic_v1.method.wrap_method( + self.list_mobile_devices, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + 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_mobile_device( + self, + ) -> Callable[ + [mobile_device_service.GetMobileDeviceRequest], + Union[ + mobile_device_messages.MobileDevice, + Awaitable[mobile_device_messages.MobileDevice], + ], + ]: + raise NotImplementedError() + + @property + def list_mobile_devices( + self, + ) -> Callable[ + [mobile_device_service.ListMobileDevicesRequest], + Union[ + mobile_device_service.ListMobileDevicesResponse, + Awaitable[mobile_device_service.ListMobileDevicesResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("MobileDeviceServiceTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/transports/rest.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/transports/rest.py new file mode 100644 index 000000000000..04da8951ea26 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/transports/rest.py @@ -0,0 +1,789 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.ads.admanager_v1.types import mobile_device_messages, mobile_device_service + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseMobileDeviceServiceRestTransport + +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 = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class MobileDeviceServiceRestInterceptor: + """Interceptor for MobileDeviceService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the MobileDeviceServiceRestTransport. + + .. code-block:: python + class MyCustomMobileDeviceServiceInterceptor(MobileDeviceServiceRestInterceptor): + def pre_get_mobile_device(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_mobile_device(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_mobile_devices(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_mobile_devices(self, response): + logging.log(f"Received response: {response}") + return response + + transport = MobileDeviceServiceRestTransport(interceptor=MyCustomMobileDeviceServiceInterceptor()) + client = MobileDeviceServiceClient(transport=transport) + + + """ + + def pre_get_mobile_device( + self, + request: mobile_device_service.GetMobileDeviceRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + mobile_device_service.GetMobileDeviceRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for get_mobile_device + + Override in a subclass to manipulate the request or metadata + before they are sent to the MobileDeviceService server. + """ + return request, metadata + + def post_get_mobile_device( + self, response: mobile_device_messages.MobileDevice + ) -> mobile_device_messages.MobileDevice: + """Post-rpc interceptor for get_mobile_device + + DEPRECATED. Please use the `post_get_mobile_device_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the MobileDeviceService server but before + it is returned to user code. This `post_get_mobile_device` interceptor runs + before the `post_get_mobile_device_with_metadata` interceptor. + """ + return response + + def post_get_mobile_device_with_metadata( + self, + response: mobile_device_messages.MobileDevice, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + mobile_device_messages.MobileDevice, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_mobile_device + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the MobileDeviceService server but before it is returned to user code. + + We recommend only using this `post_get_mobile_device_with_metadata` + interceptor in new development instead of the `post_get_mobile_device` interceptor. + When both interceptors are used, this `post_get_mobile_device_with_metadata` interceptor runs after the + `post_get_mobile_device` interceptor. The (possibly modified) response returned by + `post_get_mobile_device` will be passed to + `post_get_mobile_device_with_metadata`. + """ + return response, metadata + + def pre_list_mobile_devices( + self, + request: mobile_device_service.ListMobileDevicesRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + mobile_device_service.ListMobileDevicesRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for list_mobile_devices + + Override in a subclass to manipulate the request or metadata + before they are sent to the MobileDeviceService server. + """ + return request, metadata + + def post_list_mobile_devices( + self, response: mobile_device_service.ListMobileDevicesResponse + ) -> mobile_device_service.ListMobileDevicesResponse: + """Post-rpc interceptor for list_mobile_devices + + DEPRECATED. Please use the `post_list_mobile_devices_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the MobileDeviceService server but before + it is returned to user code. This `post_list_mobile_devices` interceptor runs + before the `post_list_mobile_devices_with_metadata` interceptor. + """ + return response + + def post_list_mobile_devices_with_metadata( + self, + response: mobile_device_service.ListMobileDevicesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + mobile_device_service.ListMobileDevicesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_mobile_devices + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the MobileDeviceService server but before it is returned to user code. + + We recommend only using this `post_list_mobile_devices_with_metadata` + interceptor in new development instead of the `post_list_mobile_devices` interceptor. + When both interceptors are used, this `post_list_mobile_devices_with_metadata` interceptor runs after the + `post_list_mobile_devices` interceptor. The (possibly modified) response returned by + `post_list_mobile_devices` will be passed to + `post_list_mobile_devices_with_metadata`. + """ + return response, metadata + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the MobileDeviceService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the MobileDeviceService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class MobileDeviceServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: MobileDeviceServiceRestInterceptor + + +class MobileDeviceServiceRestTransport(_BaseMobileDeviceServiceRestTransport): + """REST backend synchronous transport for MobileDeviceService. + + Provides methods for handling ``MobileDevice`` objects. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[MobileDeviceServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or MobileDeviceServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _GetMobileDevice( + _BaseMobileDeviceServiceRestTransport._BaseGetMobileDevice, + MobileDeviceServiceRestStub, + ): + def __hash__(self): + return hash("MobileDeviceServiceRestTransport.GetMobileDevice") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: mobile_device_service.GetMobileDeviceRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> mobile_device_messages.MobileDevice: + r"""Call the get mobile device method over HTTP. + + Args: + request (~.mobile_device_service.GetMobileDeviceRequest): + The request object. Request object for ``GetMobileDevice`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.mobile_device_messages.MobileDevice: + Represents a mobile device. + """ + + http_options = ( + _BaseMobileDeviceServiceRestTransport._BaseGetMobileDevice._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_mobile_device( + request, metadata + ) + transcoded_request = _BaseMobileDeviceServiceRestTransport._BaseGetMobileDevice._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseMobileDeviceServiceRestTransport._BaseGetMobileDevice._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.MobileDeviceServiceClient.GetMobileDevice", + extra={ + "serviceName": "google.ads.admanager.v1.MobileDeviceService", + "rpcName": "GetMobileDevice", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = MobileDeviceServiceRestTransport._GetMobileDevice._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = mobile_device_messages.MobileDevice() + pb_resp = mobile_device_messages.MobileDevice.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_mobile_device(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_mobile_device_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = mobile_device_messages.MobileDevice.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.MobileDeviceServiceClient.get_mobile_device", + extra={ + "serviceName": "google.ads.admanager.v1.MobileDeviceService", + "rpcName": "GetMobileDevice", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListMobileDevices( + _BaseMobileDeviceServiceRestTransport._BaseListMobileDevices, + MobileDeviceServiceRestStub, + ): + def __hash__(self): + return hash("MobileDeviceServiceRestTransport.ListMobileDevices") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: mobile_device_service.ListMobileDevicesRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> mobile_device_service.ListMobileDevicesResponse: + r"""Call the list mobile devices method over HTTP. + + Args: + request (~.mobile_device_service.ListMobileDevicesRequest): + The request object. Request object for ``ListMobileDevices`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.mobile_device_service.ListMobileDevicesResponse: + Response object for ``ListMobileDevicesRequest`` + containing matching ``MobileDevice`` objects. + + """ + + http_options = ( + _BaseMobileDeviceServiceRestTransport._BaseListMobileDevices._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_mobile_devices( + request, metadata + ) + transcoded_request = _BaseMobileDeviceServiceRestTransport._BaseListMobileDevices._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseMobileDeviceServiceRestTransport._BaseListMobileDevices._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.MobileDeviceServiceClient.ListMobileDevices", + extra={ + "serviceName": "google.ads.admanager.v1.MobileDeviceService", + "rpcName": "ListMobileDevices", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + MobileDeviceServiceRestTransport._ListMobileDevices._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = mobile_device_service.ListMobileDevicesResponse() + pb_resp = mobile_device_service.ListMobileDevicesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_mobile_devices(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_mobile_devices_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + mobile_device_service.ListMobileDevicesResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.MobileDeviceServiceClient.list_mobile_devices", + extra={ + "serviceName": "google.ads.admanager.v1.MobileDeviceService", + "rpcName": "ListMobileDevices", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def get_mobile_device( + self, + ) -> Callable[ + [mobile_device_service.GetMobileDeviceRequest], + mobile_device_messages.MobileDevice, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetMobileDevice(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_mobile_devices( + self, + ) -> Callable[ + [mobile_device_service.ListMobileDevicesRequest], + mobile_device_service.ListMobileDevicesResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListMobileDevices(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseMobileDeviceServiceRestTransport._BaseGetOperation, + MobileDeviceServiceRestStub, + ): + def __hash__(self): + return hash("MobileDeviceServiceRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = ( + _BaseMobileDeviceServiceRestTransport._BaseGetOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = _BaseMobileDeviceServiceRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseMobileDeviceServiceRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.MobileDeviceServiceClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.MobileDeviceService", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = MobileDeviceServiceRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.MobileDeviceServiceAsyncClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.MobileDeviceService", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("MobileDeviceServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/transports/rest_base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/transports/rest_base.py new file mode 100644 index 000000000000..e7f14519c7ab --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_service/transports/rest_base.py @@ -0,0 +1,211 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.ads.admanager_v1.types import mobile_device_messages, mobile_device_service + +from .base import DEFAULT_CLIENT_INFO, MobileDeviceServiceTransport + + +class _BaseMobileDeviceServiceRestTransport(MobileDeviceServiceTransport): + """Base REST backend transport for MobileDeviceService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetMobileDevice: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/mobileDevices/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = mobile_device_service.GetMobileDeviceRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseMobileDeviceServiceRestTransport._BaseGetMobileDevice._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListMobileDevices: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=networks/*}/mobileDevices", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = mobile_device_service.ListMobileDevicesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseMobileDeviceServiceRestTransport._BaseListMobileDevices._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/operations/reports/runs/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseMobileDeviceServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/__init__.py new file mode 100644 index 000000000000..485d4f848eef --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MobileDeviceSubmodelServiceClient + +__all__ = ("MobileDeviceSubmodelServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/client.py new file mode 100644 index 000000000000..cbaa93ac92c6 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/client.py @@ -0,0 +1,1085 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +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.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version + +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.longrunning import operations_pb2 # type: ignore + +from google.ads.admanager_v1.services.mobile_device_submodel_service import pagers +from google.ads.admanager_v1.types import ( + mobile_device_submodel_messages, + mobile_device_submodel_service, +) + +from .transports.base import DEFAULT_CLIENT_INFO, MobileDeviceSubmodelServiceTransport +from .transports.rest import MobileDeviceSubmodelServiceRestTransport + + +class MobileDeviceSubmodelServiceClientMeta(type): + """Metaclass for the MobileDeviceSubmodelService 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[MobileDeviceSubmodelServiceTransport]] + _transport_registry["rest"] = MobileDeviceSubmodelServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[MobileDeviceSubmodelServiceTransport]: + """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 MobileDeviceSubmodelServiceClient( + metaclass=MobileDeviceSubmodelServiceClientMeta +): + """Provides methods for handling ``MobileDeviceSubmodel`` objects.""" + + @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 = "admanager.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "admanager.{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: + MobileDeviceSubmodelServiceClient: 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: + MobileDeviceSubmodelServiceClient: 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) -> MobileDeviceSubmodelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + MobileDeviceSubmodelServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def mobile_device_path( + network_code: str, + mobile_device: str, + ) -> str: + """Returns a fully-qualified mobile_device string.""" + return "networks/{network_code}/mobileDevices/{mobile_device}".format( + network_code=network_code, + mobile_device=mobile_device, + ) + + @staticmethod + def parse_mobile_device_path(path: str) -> Dict[str, str]: + """Parses a mobile_device path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/mobileDevices/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def mobile_device_submodel_path( + network_code: str, + mobile_device_submodel: str, + ) -> str: + """Returns a fully-qualified mobile_device_submodel string.""" + return "networks/{network_code}/mobileDeviceSubmodels/{mobile_device_submodel}".format( + network_code=network_code, + mobile_device_submodel=mobile_device_submodel, + ) + + @staticmethod + def parse_mobile_device_submodel_path(path: str) -> Dict[str, str]: + """Parses a mobile_device_submodel path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/mobileDeviceSubmodels/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def network_path( + network_code: str, + ) -> str: + """Returns a fully-qualified network string.""" + return "networks/{network_code}".format( + network_code=network_code, + ) + + @staticmethod + def parse_network_path(path: str) -> Dict[str, str]: + """Parses a network path into its component segments.""" + m = re.match(r"^networks/(?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 = MobileDeviceSubmodelServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = MobileDeviceSubmodelServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + MobileDeviceSubmodelServiceClient._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 = MobileDeviceSubmodelServiceClient._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, + MobileDeviceSubmodelServiceTransport, + Callable[..., MobileDeviceSubmodelServiceTransport], + ] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the mobile device submodel 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,MobileDeviceSubmodelServiceTransport,Callable[..., MobileDeviceSubmodelServiceTransport]]]): + 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 MobileDeviceSubmodelServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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, + ) = MobileDeviceSubmodelServiceClient._read_environment_variables() + self._client_cert_source = ( + MobileDeviceSubmodelServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = MobileDeviceSubmodelServiceClient._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, MobileDeviceSubmodelServiceTransport) + if transport_provided: + # transport is a MobileDeviceSubmodelServiceTransport 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(MobileDeviceSubmodelServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or MobileDeviceSubmodelServiceClient._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[MobileDeviceSubmodelServiceTransport], + Callable[..., MobileDeviceSubmodelServiceTransport], + ] = ( + MobileDeviceSubmodelServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., MobileDeviceSubmodelServiceTransport], 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.admanager_v1.MobileDeviceSubmodelServiceClient`.", + extra={ + "serviceName": "google.ads.admanager.v1.MobileDeviceSubmodelService", + "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.admanager.v1.MobileDeviceSubmodelService", + "credentialsType": None, + }, + ) + + def get_mobile_device_submodel( + self, + request: Optional[ + Union[mobile_device_submodel_service.GetMobileDeviceSubmodelRequest, dict] + ] = None, + *, + 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]]] = (), + ) -> mobile_device_submodel_messages.MobileDeviceSubmodel: + r"""API to retrieve a ``MobileDeviceSubmodel`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_get_mobile_device_submodel(): + # Create a client + client = admanager_v1.MobileDeviceSubmodelServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetMobileDeviceSubmodelRequest( + name="name_value", + ) + + # Make the request + response = client.get_mobile_device_submodel(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.GetMobileDeviceSubmodelRequest, dict]): + The request object. Request object for ``GetMobileDeviceSubmodel`` method. + name (str): + Required. The resource name of the MobileDeviceSubmodel. + Format: + ``networks/{network_code}/mobileDeviceSubmodels/{mobile_device_submodel_id}`` + + This corresponds to the ``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.admanager_v1.types.MobileDeviceSubmodel: + Represents a mobile device submodel. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, mobile_device_submodel_service.GetMobileDeviceSubmodelRequest + ): + request = mobile_device_submodel_service.GetMobileDeviceSubmodelRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.get_mobile_device_submodel + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_mobile_device_submodels( + self, + request: Optional[ + Union[mobile_device_submodel_service.ListMobileDeviceSubmodelsRequest, dict] + ] = None, + *, + parent: 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.ListMobileDeviceSubmodelsPager: + r"""API to retrieve a list of ``MobileDeviceSubmodel`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_list_mobile_device_submodels(): + # Create a client + client = admanager_v1.MobileDeviceSubmodelServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListMobileDeviceSubmodelsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_mobile_device_submodels(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.ListMobileDeviceSubmodelsRequest, dict]): + The request object. Request object for ``ListMobileDeviceSubmodels`` method. + parent (str): + Required. The parent, which owns this collection of + MobileDeviceSubmodels. Format: + ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.services.mobile_device_submodel_service.pagers.ListMobileDeviceSubmodelsPager: + Response object for ListMobileDeviceSubmodelsRequest containing matching + MobileDeviceSubmodel objects. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, mobile_device_submodel_service.ListMobileDeviceSubmodelsRequest + ): + request = mobile_device_submodel_service.ListMobileDeviceSubmodelsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_mobile_device_submodels + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.ListMobileDeviceSubmodelsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "MobileDeviceSubmodelServiceClient": + 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() + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("MobileDeviceSubmodelServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/pagers.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/pagers.py new file mode 100644 index 000000000000..5f3b655437c1 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/pagers.py @@ -0,0 +1,128 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +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 + +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.admanager_v1.types import ( + mobile_device_submodel_messages, + mobile_device_submodel_service, +) + + +class ListMobileDeviceSubmodelsPager: + """A pager for iterating through ``list_mobile_device_submodels`` requests. + + This class thinly wraps an initial + :class:`google.ads.admanager_v1.types.ListMobileDeviceSubmodelsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``mobile_device_submodels`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListMobileDeviceSubmodels`` requests and continue to iterate + through the ``mobile_device_submodels`` field on the + corresponding responses. + + All the usual :class:`google.ads.admanager_v1.types.ListMobileDeviceSubmodelsResponse` + 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[ + ..., mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse + ], + request: mobile_device_submodel_service.ListMobileDeviceSubmodelsRequest, + response: mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse, + *, + 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.admanager_v1.types.ListMobileDeviceSubmodelsRequest): + The initial request object. + response (google.ads.admanager_v1.types.ListMobileDeviceSubmodelsResponse): + 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 = mobile_device_submodel_service.ListMobileDeviceSubmodelsRequest( + 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[mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse]: + 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[mobile_device_submodel_messages.MobileDeviceSubmodel]: + for page in self.pages: + yield from page.mobile_device_submodels + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/transports/README.rst b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/transports/README.rst new file mode 100644 index 000000000000..b8ff4cf01ee3 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`MobileDeviceSubmodelServiceTransport` is the ABC for all transports. +- public child `MobileDeviceSubmodelServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `MobileDeviceSubmodelServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseMobileDeviceSubmodelServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `MobileDeviceSubmodelServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/transports/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/transports/__init__.py new file mode 100644 index 000000000000..14eed448f6dd --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/transports/__init__.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 typing import Dict, Type + +from .base import MobileDeviceSubmodelServiceTransport +from .rest import ( + MobileDeviceSubmodelServiceRestInterceptor, + MobileDeviceSubmodelServiceRestTransport, +) + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[MobileDeviceSubmodelServiceTransport]] +_transport_registry["rest"] = MobileDeviceSubmodelServiceRestTransport + +__all__ = ( + "MobileDeviceSubmodelServiceTransport", + "MobileDeviceSubmodelServiceRestTransport", + "MobileDeviceSubmodelServiceRestInterceptor", +) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/transports/base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/transports/base.py new file mode 100644 index 000000000000..4313cfa7f779 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/transports/base.py @@ -0,0 +1,204 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version +from google.ads.admanager_v1.types import ( + mobile_device_submodel_messages, + mobile_device_submodel_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 MobileDeviceSubmodelServiceTransport(abc.ABC): + """Abstract transport class for MobileDeviceSubmodelService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/admanager",) + + DEFAULT_HOST: str = "admanager.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: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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_mobile_device_submodel: gapic_v1.method.wrap_method( + self.get_mobile_device_submodel, + default_timeout=None, + client_info=client_info, + ), + self.list_mobile_device_submodels: gapic_v1.method.wrap_method( + self.list_mobile_device_submodels, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + 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_mobile_device_submodel( + self, + ) -> Callable[ + [mobile_device_submodel_service.GetMobileDeviceSubmodelRequest], + Union[ + mobile_device_submodel_messages.MobileDeviceSubmodel, + Awaitable[mobile_device_submodel_messages.MobileDeviceSubmodel], + ], + ]: + raise NotImplementedError() + + @property + def list_mobile_device_submodels( + self, + ) -> Callable[ + [mobile_device_submodel_service.ListMobileDeviceSubmodelsRequest], + Union[ + mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse, + Awaitable[mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("MobileDeviceSubmodelServiceTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/transports/rest.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/transports/rest.py new file mode 100644 index 000000000000..a5e16dbe9bce --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/transports/rest.py @@ -0,0 +1,805 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.ads.admanager_v1.types import ( + mobile_device_submodel_messages, + mobile_device_submodel_service, +) + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseMobileDeviceSubmodelServiceRestTransport + +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 = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class MobileDeviceSubmodelServiceRestInterceptor: + """Interceptor for MobileDeviceSubmodelService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the MobileDeviceSubmodelServiceRestTransport. + + .. code-block:: python + class MyCustomMobileDeviceSubmodelServiceInterceptor(MobileDeviceSubmodelServiceRestInterceptor): + def pre_get_mobile_device_submodel(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_mobile_device_submodel(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_mobile_device_submodels(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_mobile_device_submodels(self, response): + logging.log(f"Received response: {response}") + return response + + transport = MobileDeviceSubmodelServiceRestTransport(interceptor=MyCustomMobileDeviceSubmodelServiceInterceptor()) + client = MobileDeviceSubmodelServiceClient(transport=transport) + + + """ + + def pre_get_mobile_device_submodel( + self, + request: mobile_device_submodel_service.GetMobileDeviceSubmodelRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + mobile_device_submodel_service.GetMobileDeviceSubmodelRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for get_mobile_device_submodel + + Override in a subclass to manipulate the request or metadata + before they are sent to the MobileDeviceSubmodelService server. + """ + return request, metadata + + def post_get_mobile_device_submodel( + self, response: mobile_device_submodel_messages.MobileDeviceSubmodel + ) -> mobile_device_submodel_messages.MobileDeviceSubmodel: + """Post-rpc interceptor for get_mobile_device_submodel + + DEPRECATED. Please use the `post_get_mobile_device_submodel_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the MobileDeviceSubmodelService server but before + it is returned to user code. This `post_get_mobile_device_submodel` interceptor runs + before the `post_get_mobile_device_submodel_with_metadata` interceptor. + """ + return response + + def post_get_mobile_device_submodel_with_metadata( + self, + response: mobile_device_submodel_messages.MobileDeviceSubmodel, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + mobile_device_submodel_messages.MobileDeviceSubmodel, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for get_mobile_device_submodel + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the MobileDeviceSubmodelService server but before it is returned to user code. + + We recommend only using this `post_get_mobile_device_submodel_with_metadata` + interceptor in new development instead of the `post_get_mobile_device_submodel` interceptor. + When both interceptors are used, this `post_get_mobile_device_submodel_with_metadata` interceptor runs after the + `post_get_mobile_device_submodel` interceptor. The (possibly modified) response returned by + `post_get_mobile_device_submodel` will be passed to + `post_get_mobile_device_submodel_with_metadata`. + """ + return response, metadata + + def pre_list_mobile_device_submodels( + self, + request: mobile_device_submodel_service.ListMobileDeviceSubmodelsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + mobile_device_submodel_service.ListMobileDeviceSubmodelsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for list_mobile_device_submodels + + Override in a subclass to manipulate the request or metadata + before they are sent to the MobileDeviceSubmodelService server. + """ + return request, metadata + + def post_list_mobile_device_submodels( + self, response: mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse + ) -> mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse: + """Post-rpc interceptor for list_mobile_device_submodels + + DEPRECATED. Please use the `post_list_mobile_device_submodels_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the MobileDeviceSubmodelService server but before + it is returned to user code. This `post_list_mobile_device_submodels` interceptor runs + before the `post_list_mobile_device_submodels_with_metadata` interceptor. + """ + return response + + def post_list_mobile_device_submodels_with_metadata( + self, + response: mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_mobile_device_submodels + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the MobileDeviceSubmodelService server but before it is returned to user code. + + We recommend only using this `post_list_mobile_device_submodels_with_metadata` + interceptor in new development instead of the `post_list_mobile_device_submodels` interceptor. + When both interceptors are used, this `post_list_mobile_device_submodels_with_metadata` interceptor runs after the + `post_list_mobile_device_submodels` interceptor. The (possibly modified) response returned by + `post_list_mobile_device_submodels` will be passed to + `post_list_mobile_device_submodels_with_metadata`. + """ + return response, metadata + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the MobileDeviceSubmodelService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the MobileDeviceSubmodelService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class MobileDeviceSubmodelServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: MobileDeviceSubmodelServiceRestInterceptor + + +class MobileDeviceSubmodelServiceRestTransport( + _BaseMobileDeviceSubmodelServiceRestTransport +): + """REST backend synchronous transport for MobileDeviceSubmodelService. + + Provides methods for handling ``MobileDeviceSubmodel`` objects. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[MobileDeviceSubmodelServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or MobileDeviceSubmodelServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _GetMobileDeviceSubmodel( + _BaseMobileDeviceSubmodelServiceRestTransport._BaseGetMobileDeviceSubmodel, + MobileDeviceSubmodelServiceRestStub, + ): + def __hash__(self): + return hash( + "MobileDeviceSubmodelServiceRestTransport.GetMobileDeviceSubmodel" + ) + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: mobile_device_submodel_service.GetMobileDeviceSubmodelRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> mobile_device_submodel_messages.MobileDeviceSubmodel: + r"""Call the get mobile device + submodel method over HTTP. + + Args: + request (~.mobile_device_submodel_service.GetMobileDeviceSubmodelRequest): + The request object. Request object for ``GetMobileDeviceSubmodel`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.mobile_device_submodel_messages.MobileDeviceSubmodel: + Represents a mobile device submodel. + """ + + http_options = ( + _BaseMobileDeviceSubmodelServiceRestTransport._BaseGetMobileDeviceSubmodel._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_mobile_device_submodel( + request, metadata + ) + transcoded_request = _BaseMobileDeviceSubmodelServiceRestTransport._BaseGetMobileDeviceSubmodel._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseMobileDeviceSubmodelServiceRestTransport._BaseGetMobileDeviceSubmodel._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.MobileDeviceSubmodelServiceClient.GetMobileDeviceSubmodel", + extra={ + "serviceName": "google.ads.admanager.v1.MobileDeviceSubmodelService", + "rpcName": "GetMobileDeviceSubmodel", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = MobileDeviceSubmodelServiceRestTransport._GetMobileDeviceSubmodel._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = mobile_device_submodel_messages.MobileDeviceSubmodel() + pb_resp = mobile_device_submodel_messages.MobileDeviceSubmodel.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_mobile_device_submodel(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_mobile_device_submodel_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + mobile_device_submodel_messages.MobileDeviceSubmodel.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.MobileDeviceSubmodelServiceClient.get_mobile_device_submodel", + extra={ + "serviceName": "google.ads.admanager.v1.MobileDeviceSubmodelService", + "rpcName": "GetMobileDeviceSubmodel", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListMobileDeviceSubmodels( + _BaseMobileDeviceSubmodelServiceRestTransport._BaseListMobileDeviceSubmodels, + MobileDeviceSubmodelServiceRestStub, + ): + def __hash__(self): + return hash( + "MobileDeviceSubmodelServiceRestTransport.ListMobileDeviceSubmodels" + ) + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: mobile_device_submodel_service.ListMobileDeviceSubmodelsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse: + r"""Call the list mobile device + submodels method over HTTP. + + Args: + request (~.mobile_device_submodel_service.ListMobileDeviceSubmodelsRequest): + The request object. Request object for ``ListMobileDeviceSubmodels`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse: + Response object for ``ListMobileDeviceSubmodelsRequest`` + containing matching ``MobileDeviceSubmodel`` objects. + + """ + + http_options = ( + _BaseMobileDeviceSubmodelServiceRestTransport._BaseListMobileDeviceSubmodels._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_mobile_device_submodels( + request, metadata + ) + transcoded_request = _BaseMobileDeviceSubmodelServiceRestTransport._BaseListMobileDeviceSubmodels._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseMobileDeviceSubmodelServiceRestTransport._BaseListMobileDeviceSubmodels._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.MobileDeviceSubmodelServiceClient.ListMobileDeviceSubmodels", + extra={ + "serviceName": "google.ads.admanager.v1.MobileDeviceSubmodelService", + "rpcName": "ListMobileDeviceSubmodels", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = MobileDeviceSubmodelServiceRestTransport._ListMobileDeviceSubmodels._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse() + pb_resp = ( + mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse.pb( + resp + ) + ) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_mobile_device_submodels(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_mobile_device_submodels_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.MobileDeviceSubmodelServiceClient.list_mobile_device_submodels", + extra={ + "serviceName": "google.ads.admanager.v1.MobileDeviceSubmodelService", + "rpcName": "ListMobileDeviceSubmodels", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def get_mobile_device_submodel( + self, + ) -> Callable[ + [mobile_device_submodel_service.GetMobileDeviceSubmodelRequest], + mobile_device_submodel_messages.MobileDeviceSubmodel, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetMobileDeviceSubmodel(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_mobile_device_submodels( + self, + ) -> Callable[ + [mobile_device_submodel_service.ListMobileDeviceSubmodelsRequest], + mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListMobileDeviceSubmodels(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseMobileDeviceSubmodelServiceRestTransport._BaseGetOperation, + MobileDeviceSubmodelServiceRestStub, + ): + def __hash__(self): + return hash("MobileDeviceSubmodelServiceRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = ( + _BaseMobileDeviceSubmodelServiceRestTransport._BaseGetOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = _BaseMobileDeviceSubmodelServiceRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseMobileDeviceSubmodelServiceRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.MobileDeviceSubmodelServiceClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.MobileDeviceSubmodelService", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + MobileDeviceSubmodelServiceRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.MobileDeviceSubmodelServiceAsyncClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.MobileDeviceSubmodelService", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("MobileDeviceSubmodelServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/transports/rest_base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/transports/rest_base.py new file mode 100644 index 000000000000..399a762450b6 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/mobile_device_submodel_service/transports/rest_base.py @@ -0,0 +1,224 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.ads.admanager_v1.types import ( + mobile_device_submodel_messages, + mobile_device_submodel_service, +) + +from .base import DEFAULT_CLIENT_INFO, MobileDeviceSubmodelServiceTransport + + +class _BaseMobileDeviceSubmodelServiceRestTransport( + MobileDeviceSubmodelServiceTransport +): + """Base REST backend transport for MobileDeviceSubmodelService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseGetMobileDeviceSubmodel: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/mobileDeviceSubmodels/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = ( + mobile_device_submodel_service.GetMobileDeviceSubmodelRequest.pb( + request + ) + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseMobileDeviceSubmodelServiceRestTransport._BaseGetMobileDeviceSubmodel._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListMobileDeviceSubmodels: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=networks/*}/mobileDeviceSubmodels", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = ( + mobile_device_submodel_service.ListMobileDeviceSubmodelsRequest.pb( + request + ) + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseMobileDeviceSubmodelServiceRestTransport._BaseListMobileDeviceSubmodels._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/operations/reports/runs/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseMobileDeviceSubmodelServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/placement_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/placement_service/client.py index e4a0f7540cc8..a6068df802c6 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/services/placement_service/client.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/placement_service/client.py @@ -62,6 +62,7 @@ _LOGGER = std_logging.getLogger(__name__) from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore from google.protobuf import timestamp_pb2 # type: ignore from google.ads.admanager_v1.services.placement_service import pagers @@ -972,6 +973,840 @@ def sample_list_placements(): # Done; return the response. return response + def create_placement( + self, + request: Optional[Union[placement_service.CreatePlacementRequest, dict]] = None, + *, + parent: Optional[str] = None, + placement: Optional[placement_messages.Placement] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> placement_messages.Placement: + r"""API to create an ``Placement`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_create_placement(): + # Create a client + client = admanager_v1.PlacementServiceClient() + + # Initialize request argument(s) + request = admanager_v1.CreatePlacementRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_placement(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.CreatePlacementRequest, dict]): + The request object. Request object for ``CreatePlacement`` method. + parent (str): + Required. The parent resource where this ``Placement`` + will be created. Format: ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + placement (google.ads.admanager_v1.types.Placement): + Required. The ``Placement`` to create. + This corresponds to the ``placement`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.Placement: + The Placement resource. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, placement] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, placement_service.CreatePlacementRequest): + request = placement_service.CreatePlacementRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if placement is not None: + request.placement = placement + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_placement] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe 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_placement( + self, + request: Optional[Union[placement_service.UpdatePlacementRequest, dict]] = None, + *, + placement: Optional[placement_messages.Placement] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> placement_messages.Placement: + r"""API to update an ``Placement`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_update_placement(): + # Create a client + client = admanager_v1.PlacementServiceClient() + + # Initialize request argument(s) + request = admanager_v1.UpdatePlacementRequest( + ) + + # Make the request + response = client.update_placement(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.UpdatePlacementRequest, dict]): + The request object. Request object for ``UpdatePlacement`` method. + placement (google.ads.admanager_v1.types.Placement): + Required. The ``Placement`` to update. + + The ``Placement``'s name is used to identify the + ``Placement`` to update. Format: + ``networks/{network_code}/placements/{placement_id}`` + + This corresponds to the ``placement`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Required. The list of fields to + update. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.Placement: + The Placement resource. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [placement, update_mask] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, placement_service.UpdatePlacementRequest): + request = placement_service.UpdatePlacementRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if placement is not None: + request.placement = placement + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_placement] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("placement.name", request.placement.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 batch_create_placements( + self, + request: Optional[ + Union[placement_service.BatchCreatePlacementsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + requests: Optional[ + MutableSequence[placement_service.CreatePlacementRequest] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> placement_service.BatchCreatePlacementsResponse: + r"""API to batch create ``Placement`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_batch_create_placements(): + # Create a client + client = admanager_v1.PlacementServiceClient() + + # Initialize request argument(s) + requests = admanager_v1.CreatePlacementRequest() + requests.parent = "parent_value" + + request = admanager_v1.BatchCreatePlacementsRequest( + parent="parent_value", + requests=requests, + ) + + # Make the request + response = client.batch_create_placements(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.BatchCreatePlacementsRequest, dict]): + The request object. Request object for ``BatchCreatePlacements`` method. + parent (str): + Required. The parent resource where the ``Placement``\ s + will be created. Format: ``networks/{network_code}`` The + parent field in the CreatePlacementRequest messages + match this field. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + requests (MutableSequence[google.ads.admanager_v1.types.CreatePlacementRequest]): + Required. The ``Placement`` objects to create. A maximum + of 100 objects can be created in a batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.BatchCreatePlacementsResponse: + Response object for BatchCreatePlacements method. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, requests] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, placement_service.BatchCreatePlacementsRequest): + request = placement_service.BatchCreatePlacementsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_create_placements] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def batch_update_placements( + self, + request: Optional[ + Union[placement_service.BatchUpdatePlacementsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + requests: Optional[ + MutableSequence[placement_service.UpdatePlacementRequest] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> placement_service.BatchUpdatePlacementsResponse: + r"""API to batch update ``Placement`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_batch_update_placements(): + # Create a client + client = admanager_v1.PlacementServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchUpdatePlacementsRequest( + parent="parent_value", + ) + + # Make the request + response = client.batch_update_placements(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.BatchUpdatePlacementsRequest, dict]): + The request object. Request object for ``BatchUpdatePlacements`` method. + parent (str): + Required. The parent resource where ``Placements`` will + be updated. Format: ``networks/{network_code}`` The + parent field in the UpdatePlacementsRequest must match + this field. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + requests (MutableSequence[google.ads.admanager_v1.types.UpdatePlacementRequest]): + Required. The ``Placement`` objects to update. A maximum + of 100 objects can be updated in a batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.BatchUpdatePlacementsResponse: + Response object for BatchUpdatePlacements method. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, requests] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, placement_service.BatchUpdatePlacementsRequest): + request = placement_service.BatchUpdatePlacementsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_update_placements] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def batch_activate_placements( + self, + request: Optional[ + Union[placement_service.BatchActivatePlacementsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + names: 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]]] = (), + ) -> placement_service.BatchActivatePlacementsResponse: + r"""Activates a list of ``Placement`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_batch_activate_placements(): + # Create a client + client = admanager_v1.PlacementServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchActivatePlacementsRequest( + parent="parent_value", + names=['names_value1', 'names_value2'], + ) + + # Make the request + response = client.batch_activate_placements(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.BatchActivatePlacementsRequest, dict]): + The request object. Request message for ``BatchActivatePlacements`` method. + parent (str): + Required. Format: ``networks/{network_code}`` + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + names (MutableSequence[str]): + Required. The names of the ``Placement`` objects to + activate. Format: + ``networks/{network_code}/placements/{placement_id}`` + + This corresponds to the ``names`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.BatchActivatePlacementsResponse: + Response object for BatchActivatePlacements method. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, names] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, placement_service.BatchActivatePlacementsRequest): + request = placement_service.BatchActivatePlacementsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if names is not None: + request.names = names + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.batch_activate_placements + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def batch_deactivate_placements( + self, + request: Optional[ + Union[placement_service.BatchDeactivatePlacementsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + names: 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]]] = (), + ) -> placement_service.BatchDeactivatePlacementsResponse: + r"""Deactivates a list of ``Placement`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_batch_deactivate_placements(): + # Create a client + client = admanager_v1.PlacementServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchDeactivatePlacementsRequest( + parent="parent_value", + names=['names_value1', 'names_value2'], + ) + + # Make the request + response = client.batch_deactivate_placements(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.BatchDeactivatePlacementsRequest, dict]): + The request object. Request message for ``BatchDeactivatePlacements`` + method. + parent (str): + Required. Format: ``networks/{network_code}`` + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + names (MutableSequence[str]): + Required. The names of the ``Placement`` objects to + deactivate. Format: + ``networks/{network_code}/placements/{placement_id}`` + + This corresponds to the ``names`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.BatchDeactivatePlacementsResponse: + Response object for BatchDeactivatePlacements method. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, names] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, placement_service.BatchDeactivatePlacementsRequest): + request = placement_service.BatchDeactivatePlacementsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if names is not None: + request.names = names + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.batch_deactivate_placements + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def batch_archive_placements( + self, + request: Optional[ + Union[placement_service.BatchArchivePlacementsRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + names: 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]]] = (), + ) -> placement_service.BatchArchivePlacementsResponse: + r"""Archives a list of ``Placement`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_batch_archive_placements(): + # Create a client + client = admanager_v1.PlacementServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchArchivePlacementsRequest( + parent="parent_value", + names=['names_value1', 'names_value2'], + ) + + # Make the request + response = client.batch_archive_placements(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.BatchArchivePlacementsRequest, dict]): + The request object. Request message for ``BatchArchivePlacements`` method. + parent (str): + Required. Format: ``networks/{network_code}`` + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + names (MutableSequence[str]): + Required. The names of the ``Placement`` objects to + archive. Format: + ``networks/{network_code}/placements/{placement_id}`` + + This corresponds to the ``names`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.BatchArchivePlacementsResponse: + Response object for BatchArchivePlacements method. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, names] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, placement_service.BatchArchivePlacementsRequest): + request = placement_service.BatchArchivePlacementsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if names is not None: + request.names = names + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_archive_placements] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe 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) -> "PlacementServiceClient": return self diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/placement_service/transports/base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/placement_service/transports/base.py index 3ccdb0acb853..08426a5d7817 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/services/placement_service/transports/base.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/placement_service/transports/base.py @@ -144,6 +144,41 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.create_placement: gapic_v1.method.wrap_method( + self.create_placement, + default_timeout=None, + client_info=client_info, + ), + self.update_placement: gapic_v1.method.wrap_method( + self.update_placement, + default_timeout=None, + client_info=client_info, + ), + self.batch_create_placements: gapic_v1.method.wrap_method( + self.batch_create_placements, + default_timeout=None, + client_info=client_info, + ), + self.batch_update_placements: gapic_v1.method.wrap_method( + self.batch_update_placements, + default_timeout=None, + client_info=client_info, + ), + self.batch_activate_placements: gapic_v1.method.wrap_method( + self.batch_activate_placements, + default_timeout=None, + client_info=client_info, + ), + self.batch_deactivate_placements: gapic_v1.method.wrap_method( + self.batch_deactivate_placements, + default_timeout=None, + client_info=client_info, + ), + self.batch_archive_placements: gapic_v1.method.wrap_method( + self.batch_archive_placements, + default_timeout=None, + client_info=client_info, + ), self.get_operation: gapic_v1.method.wrap_method( self.get_operation, default_timeout=None, @@ -181,6 +216,84 @@ def list_placements( ]: raise NotImplementedError() + @property + def create_placement( + self, + ) -> Callable[ + [placement_service.CreatePlacementRequest], + Union[placement_messages.Placement, Awaitable[placement_messages.Placement]], + ]: + raise NotImplementedError() + + @property + def update_placement( + self, + ) -> Callable[ + [placement_service.UpdatePlacementRequest], + Union[placement_messages.Placement, Awaitable[placement_messages.Placement]], + ]: + raise NotImplementedError() + + @property + def batch_create_placements( + self, + ) -> Callable[ + [placement_service.BatchCreatePlacementsRequest], + Union[ + placement_service.BatchCreatePlacementsResponse, + Awaitable[placement_service.BatchCreatePlacementsResponse], + ], + ]: + raise NotImplementedError() + + @property + def batch_update_placements( + self, + ) -> Callable[ + [placement_service.BatchUpdatePlacementsRequest], + Union[ + placement_service.BatchUpdatePlacementsResponse, + Awaitable[placement_service.BatchUpdatePlacementsResponse], + ], + ]: + raise NotImplementedError() + + @property + def batch_activate_placements( + self, + ) -> Callable[ + [placement_service.BatchActivatePlacementsRequest], + Union[ + placement_service.BatchActivatePlacementsResponse, + Awaitable[placement_service.BatchActivatePlacementsResponse], + ], + ]: + raise NotImplementedError() + + @property + def batch_deactivate_placements( + self, + ) -> Callable[ + [placement_service.BatchDeactivatePlacementsRequest], + Union[ + placement_service.BatchDeactivatePlacementsResponse, + Awaitable[placement_service.BatchDeactivatePlacementsResponse], + ], + ]: + raise NotImplementedError() + + @property + def batch_archive_placements( + self, + ) -> Callable[ + [placement_service.BatchArchivePlacementsRequest], + Union[ + placement_service.BatchArchivePlacementsResponse, + Awaitable[placement_service.BatchArchivePlacementsResponse], + ], + ]: + raise NotImplementedError() + @property def get_operation( self, diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/placement_service/transports/rest.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/placement_service/transports/rest.py index b6c53ee77ced..66f812e66d80 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/services/placement_service/transports/rest.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/placement_service/transports/rest.py @@ -73,6 +73,54 @@ class PlacementServiceRestInterceptor: .. code-block:: python class MyCustomPlacementServiceInterceptor(PlacementServiceRestInterceptor): + def pre_batch_activate_placements(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_activate_placements(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_archive_placements(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_archive_placements(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_create_placements(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_create_placements(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_deactivate_placements(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_deactivate_placements(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_update_placements(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_update_placements(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_placement(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_placement(self, response): + logging.log(f"Received response: {response}") + return response + def pre_get_placement(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -89,12 +137,329 @@ def post_list_placements(self, response): logging.log(f"Received response: {response}") return response + def pre_update_placement(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_placement(self, response): + logging.log(f"Received response: {response}") + return response + transport = PlacementServiceRestTransport(interceptor=MyCustomPlacementServiceInterceptor()) client = PlacementServiceClient(transport=transport) """ + def pre_batch_activate_placements( + self, + request: placement_service.BatchActivatePlacementsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + placement_service.BatchActivatePlacementsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for batch_activate_placements + + Override in a subclass to manipulate the request or metadata + before they are sent to the PlacementService server. + """ + return request, metadata + + def post_batch_activate_placements( + self, response: placement_service.BatchActivatePlacementsResponse + ) -> placement_service.BatchActivatePlacementsResponse: + """Post-rpc interceptor for batch_activate_placements + + DEPRECATED. Please use the `post_batch_activate_placements_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the PlacementService server but before + it is returned to user code. This `post_batch_activate_placements` interceptor runs + before the `post_batch_activate_placements_with_metadata` interceptor. + """ + return response + + def post_batch_activate_placements_with_metadata( + self, + response: placement_service.BatchActivatePlacementsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + placement_service.BatchActivatePlacementsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for batch_activate_placements + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the PlacementService server but before it is returned to user code. + + We recommend only using this `post_batch_activate_placements_with_metadata` + interceptor in new development instead of the `post_batch_activate_placements` interceptor. + When both interceptors are used, this `post_batch_activate_placements_with_metadata` interceptor runs after the + `post_batch_activate_placements` interceptor. The (possibly modified) response returned by + `post_batch_activate_placements` will be passed to + `post_batch_activate_placements_with_metadata`. + """ + return response, metadata + + def pre_batch_archive_placements( + self, + request: placement_service.BatchArchivePlacementsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + placement_service.BatchArchivePlacementsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for batch_archive_placements + + Override in a subclass to manipulate the request or metadata + before they are sent to the PlacementService server. + """ + return request, metadata + + def post_batch_archive_placements( + self, response: placement_service.BatchArchivePlacementsResponse + ) -> placement_service.BatchArchivePlacementsResponse: + """Post-rpc interceptor for batch_archive_placements + + DEPRECATED. Please use the `post_batch_archive_placements_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the PlacementService server but before + it is returned to user code. This `post_batch_archive_placements` interceptor runs + before the `post_batch_archive_placements_with_metadata` interceptor. + """ + return response + + def post_batch_archive_placements_with_metadata( + self, + response: placement_service.BatchArchivePlacementsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + placement_service.BatchArchivePlacementsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for batch_archive_placements + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the PlacementService server but before it is returned to user code. + + We recommend only using this `post_batch_archive_placements_with_metadata` + interceptor in new development instead of the `post_batch_archive_placements` interceptor. + When both interceptors are used, this `post_batch_archive_placements_with_metadata` interceptor runs after the + `post_batch_archive_placements` interceptor. The (possibly modified) response returned by + `post_batch_archive_placements` will be passed to + `post_batch_archive_placements_with_metadata`. + """ + return response, metadata + + def pre_batch_create_placements( + self, + request: placement_service.BatchCreatePlacementsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + placement_service.BatchCreatePlacementsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for batch_create_placements + + Override in a subclass to manipulate the request or metadata + before they are sent to the PlacementService server. + """ + return request, metadata + + def post_batch_create_placements( + self, response: placement_service.BatchCreatePlacementsResponse + ) -> placement_service.BatchCreatePlacementsResponse: + """Post-rpc interceptor for batch_create_placements + + DEPRECATED. Please use the `post_batch_create_placements_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the PlacementService server but before + it is returned to user code. This `post_batch_create_placements` interceptor runs + before the `post_batch_create_placements_with_metadata` interceptor. + """ + return response + + def post_batch_create_placements_with_metadata( + self, + response: placement_service.BatchCreatePlacementsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + placement_service.BatchCreatePlacementsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for batch_create_placements + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the PlacementService server but before it is returned to user code. + + We recommend only using this `post_batch_create_placements_with_metadata` + interceptor in new development instead of the `post_batch_create_placements` interceptor. + When both interceptors are used, this `post_batch_create_placements_with_metadata` interceptor runs after the + `post_batch_create_placements` interceptor. The (possibly modified) response returned by + `post_batch_create_placements` will be passed to + `post_batch_create_placements_with_metadata`. + """ + return response, metadata + + def pre_batch_deactivate_placements( + self, + request: placement_service.BatchDeactivatePlacementsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + placement_service.BatchDeactivatePlacementsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for batch_deactivate_placements + + Override in a subclass to manipulate the request or metadata + before they are sent to the PlacementService server. + """ + return request, metadata + + def post_batch_deactivate_placements( + self, response: placement_service.BatchDeactivatePlacementsResponse + ) -> placement_service.BatchDeactivatePlacementsResponse: + """Post-rpc interceptor for batch_deactivate_placements + + DEPRECATED. Please use the `post_batch_deactivate_placements_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the PlacementService server but before + it is returned to user code. This `post_batch_deactivate_placements` interceptor runs + before the `post_batch_deactivate_placements_with_metadata` interceptor. + """ + return response + + def post_batch_deactivate_placements_with_metadata( + self, + response: placement_service.BatchDeactivatePlacementsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + placement_service.BatchDeactivatePlacementsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for batch_deactivate_placements + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the PlacementService server but before it is returned to user code. + + We recommend only using this `post_batch_deactivate_placements_with_metadata` + interceptor in new development instead of the `post_batch_deactivate_placements` interceptor. + When both interceptors are used, this `post_batch_deactivate_placements_with_metadata` interceptor runs after the + `post_batch_deactivate_placements` interceptor. The (possibly modified) response returned by + `post_batch_deactivate_placements` will be passed to + `post_batch_deactivate_placements_with_metadata`. + """ + return response, metadata + + def pre_batch_update_placements( + self, + request: placement_service.BatchUpdatePlacementsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + placement_service.BatchUpdatePlacementsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for batch_update_placements + + Override in a subclass to manipulate the request or metadata + before they are sent to the PlacementService server. + """ + return request, metadata + + def post_batch_update_placements( + self, response: placement_service.BatchUpdatePlacementsResponse + ) -> placement_service.BatchUpdatePlacementsResponse: + """Post-rpc interceptor for batch_update_placements + + DEPRECATED. Please use the `post_batch_update_placements_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the PlacementService server but before + it is returned to user code. This `post_batch_update_placements` interceptor runs + before the `post_batch_update_placements_with_metadata` interceptor. + """ + return response + + def post_batch_update_placements_with_metadata( + self, + response: placement_service.BatchUpdatePlacementsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + placement_service.BatchUpdatePlacementsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for batch_update_placements + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the PlacementService server but before it is returned to user code. + + We recommend only using this `post_batch_update_placements_with_metadata` + interceptor in new development instead of the `post_batch_update_placements` interceptor. + When both interceptors are used, this `post_batch_update_placements_with_metadata` interceptor runs after the + `post_batch_update_placements` interceptor. The (possibly modified) response returned by + `post_batch_update_placements` will be passed to + `post_batch_update_placements_with_metadata`. + """ + return response, metadata + + def pre_create_placement( + self, + request: placement_service.CreatePlacementRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + placement_service.CreatePlacementRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for create_placement + + Override in a subclass to manipulate the request or metadata + before they are sent to the PlacementService server. + """ + return request, metadata + + def post_create_placement( + self, response: placement_messages.Placement + ) -> placement_messages.Placement: + """Post-rpc interceptor for create_placement + + DEPRECATED. Please use the `post_create_placement_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the PlacementService server but before + it is returned to user code. This `post_create_placement` interceptor runs + before the `post_create_placement_with_metadata` interceptor. + """ + return response + + def post_create_placement_with_metadata( + self, + response: placement_messages.Placement, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[placement_messages.Placement, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_placement + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the PlacementService server but before it is returned to user code. + + We recommend only using this `post_create_placement_with_metadata` + interceptor in new development instead of the `post_create_placement` interceptor. + When both interceptors are used, this `post_create_placement_with_metadata` interceptor runs after the + `post_create_placement` interceptor. The (possibly modified) response returned by + `post_create_placement` will be passed to + `post_create_placement_with_metadata`. + """ + return response, metadata + def pre_get_placement( self, request: placement_service.GetPlacementRequest, @@ -194,37 +559,86 @@ def post_list_placements_with_metadata( """ return response, metadata - def pre_get_operation( + def pre_update_placement( self, - request: operations_pb2.GetOperationRequest, + request: placement_service.UpdatePlacementRequest, metadata: Sequence[Tuple[str, Union[str, bytes]]], ) -> Tuple[ - operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + placement_service.UpdatePlacementRequest, + Sequence[Tuple[str, Union[str, bytes]]], ]: - """Pre-rpc interceptor for get_operation + """Pre-rpc interceptor for update_placement Override in a subclass to manipulate the request or metadata before they are sent to the PlacementService server. """ return request, metadata - def post_get_operation( - self, response: operations_pb2.Operation - ) -> operations_pb2.Operation: - """Post-rpc interceptor for get_operation + def post_update_placement( + self, response: placement_messages.Placement + ) -> placement_messages.Placement: + """Post-rpc interceptor for update_placement - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_placement_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the PlacementService server but before - it is returned to user code. + it is returned to user code. This `post_update_placement` interceptor runs + before the `post_update_placement_with_metadata` interceptor. """ return response + def post_update_placement_with_metadata( + self, + response: placement_messages.Placement, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[placement_messages.Placement, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_placement -@dataclasses.dataclass -class PlacementServiceRestStub: - _session: AuthorizedSession - _host: str - _interceptor: PlacementServiceRestInterceptor + Override in a subclass to read or manipulate the response or metadata after it + is returned by the PlacementService server but before it is returned to user code. + + We recommend only using this `post_update_placement_with_metadata` + interceptor in new development instead of the `post_update_placement` interceptor. + When both interceptors are used, this `post_update_placement_with_metadata` interceptor runs after the + `post_update_placement` interceptor. The (possibly modified) response returned by + `post_update_placement` will be passed to + `post_update_placement_with_metadata`. + """ + return response, metadata + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the PlacementService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the PlacementService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class PlacementServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: PlacementServiceRestInterceptor class PlacementServiceRestTransport(_BasePlacementServiceRestTransport): @@ -256,56 +670,1008 @@ def __init__( ) -> None: """Instantiate the transport. - Args: - host (Optional[str]): - The hostname to connect to (default: 'admanager.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or PlacementServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _BatchActivatePlacements( + _BasePlacementServiceRestTransport._BaseBatchActivatePlacements, + PlacementServiceRestStub, + ): + def __hash__(self): + return hash("PlacementServiceRestTransport.BatchActivatePlacements") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: placement_service.BatchActivatePlacementsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> placement_service.BatchActivatePlacementsResponse: + r"""Call the batch activate placements method over HTTP. + + Args: + request (~.placement_service.BatchActivatePlacementsRequest): + The request object. Request message for ``BatchActivatePlacements`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.placement_service.BatchActivatePlacementsResponse: + Response object for ``BatchActivatePlacements`` method. + """ + + http_options = ( + _BasePlacementServiceRestTransport._BaseBatchActivatePlacements._get_http_options() + ) + + request, metadata = self._interceptor.pre_batch_activate_placements( + request, metadata + ) + transcoded_request = _BasePlacementServiceRestTransport._BaseBatchActivatePlacements._get_transcoded_request( + http_options, request + ) + + body = _BasePlacementServiceRestTransport._BaseBatchActivatePlacements._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BasePlacementServiceRestTransport._BaseBatchActivatePlacements._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.PlacementServiceClient.BatchActivatePlacements", + extra={ + "serviceName": "google.ads.admanager.v1.PlacementService", + "rpcName": "BatchActivatePlacements", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + PlacementServiceRestTransport._BatchActivatePlacements._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = placement_service.BatchActivatePlacementsResponse() + pb_resp = placement_service.BatchActivatePlacementsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_activate_placements(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_activate_placements_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + placement_service.BatchActivatePlacementsResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.PlacementServiceClient.batch_activate_placements", + extra={ + "serviceName": "google.ads.admanager.v1.PlacementService", + "rpcName": "BatchActivatePlacements", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _BatchArchivePlacements( + _BasePlacementServiceRestTransport._BaseBatchArchivePlacements, + PlacementServiceRestStub, + ): + def __hash__(self): + return hash("PlacementServiceRestTransport.BatchArchivePlacements") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: placement_service.BatchArchivePlacementsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> placement_service.BatchArchivePlacementsResponse: + r"""Call the batch archive placements method over HTTP. + + Args: + request (~.placement_service.BatchArchivePlacementsRequest): + The request object. Request message for ``BatchArchivePlacements`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.placement_service.BatchArchivePlacementsResponse: + Response object for ``BatchArchivePlacements`` method. + """ + + http_options = ( + _BasePlacementServiceRestTransport._BaseBatchArchivePlacements._get_http_options() + ) + + request, metadata = self._interceptor.pre_batch_archive_placements( + request, metadata + ) + transcoded_request = _BasePlacementServiceRestTransport._BaseBatchArchivePlacements._get_transcoded_request( + http_options, request + ) + + body = _BasePlacementServiceRestTransport._BaseBatchArchivePlacements._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BasePlacementServiceRestTransport._BaseBatchArchivePlacements._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.PlacementServiceClient.BatchArchivePlacements", + extra={ + "serviceName": "google.ads.admanager.v1.PlacementService", + "rpcName": "BatchArchivePlacements", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + PlacementServiceRestTransport._BatchArchivePlacements._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = placement_service.BatchArchivePlacementsResponse() + pb_resp = placement_service.BatchArchivePlacementsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_archive_placements(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_archive_placements_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + placement_service.BatchArchivePlacementsResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.PlacementServiceClient.batch_archive_placements", + extra={ + "serviceName": "google.ads.admanager.v1.PlacementService", + "rpcName": "BatchArchivePlacements", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _BatchCreatePlacements( + _BasePlacementServiceRestTransport._BaseBatchCreatePlacements, + PlacementServiceRestStub, + ): + def __hash__(self): + return hash("PlacementServiceRestTransport.BatchCreatePlacements") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: placement_service.BatchCreatePlacementsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> placement_service.BatchCreatePlacementsResponse: + r"""Call the batch create placements method over HTTP. + + Args: + request (~.placement_service.BatchCreatePlacementsRequest): + The request object. Request object for ``BatchCreatePlacements`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.placement_service.BatchCreatePlacementsResponse: + Response object for ``BatchCreatePlacements`` method. + """ + + http_options = ( + _BasePlacementServiceRestTransport._BaseBatchCreatePlacements._get_http_options() + ) + + request, metadata = self._interceptor.pre_batch_create_placements( + request, metadata + ) + transcoded_request = _BasePlacementServiceRestTransport._BaseBatchCreatePlacements._get_transcoded_request( + http_options, request + ) + + body = _BasePlacementServiceRestTransport._BaseBatchCreatePlacements._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BasePlacementServiceRestTransport._BaseBatchCreatePlacements._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.PlacementServiceClient.BatchCreatePlacements", + extra={ + "serviceName": "google.ads.admanager.v1.PlacementService", + "rpcName": "BatchCreatePlacements", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + PlacementServiceRestTransport._BatchCreatePlacements._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = placement_service.BatchCreatePlacementsResponse() + pb_resp = placement_service.BatchCreatePlacementsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_create_placements(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_create_placements_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + placement_service.BatchCreatePlacementsResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.PlacementServiceClient.batch_create_placements", + extra={ + "serviceName": "google.ads.admanager.v1.PlacementService", + "rpcName": "BatchCreatePlacements", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _BatchDeactivatePlacements( + _BasePlacementServiceRestTransport._BaseBatchDeactivatePlacements, + PlacementServiceRestStub, + ): + def __hash__(self): + return hash("PlacementServiceRestTransport.BatchDeactivatePlacements") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: placement_service.BatchDeactivatePlacementsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> placement_service.BatchDeactivatePlacementsResponse: + r"""Call the batch deactivate + placements method over HTTP. + + Args: + request (~.placement_service.BatchDeactivatePlacementsRequest): + The request object. Request message for ``BatchDeactivatePlacements`` + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.placement_service.BatchDeactivatePlacementsResponse: + Response object for ``BatchDeactivatePlacements`` + method. + + """ + + http_options = ( + _BasePlacementServiceRestTransport._BaseBatchDeactivatePlacements._get_http_options() + ) + + request, metadata = self._interceptor.pre_batch_deactivate_placements( + request, metadata + ) + transcoded_request = _BasePlacementServiceRestTransport._BaseBatchDeactivatePlacements._get_transcoded_request( + http_options, request + ) + + body = _BasePlacementServiceRestTransport._BaseBatchDeactivatePlacements._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BasePlacementServiceRestTransport._BaseBatchDeactivatePlacements._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.PlacementServiceClient.BatchDeactivatePlacements", + extra={ + "serviceName": "google.ads.admanager.v1.PlacementService", + "rpcName": "BatchDeactivatePlacements", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + PlacementServiceRestTransport._BatchDeactivatePlacements._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = placement_service.BatchDeactivatePlacementsResponse() + pb_resp = placement_service.BatchDeactivatePlacementsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_deactivate_placements(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_deactivate_placements_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + placement_service.BatchDeactivatePlacementsResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.PlacementServiceClient.batch_deactivate_placements", + extra={ + "serviceName": "google.ads.admanager.v1.PlacementService", + "rpcName": "BatchDeactivatePlacements", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _BatchUpdatePlacements( + _BasePlacementServiceRestTransport._BaseBatchUpdatePlacements, + PlacementServiceRestStub, + ): + def __hash__(self): + return hash("PlacementServiceRestTransport.BatchUpdatePlacements") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: placement_service.BatchUpdatePlacementsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> placement_service.BatchUpdatePlacementsResponse: + r"""Call the batch update placements method over HTTP. + + Args: + request (~.placement_service.BatchUpdatePlacementsRequest): + The request object. Request object for ``BatchUpdatePlacements`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.placement_service.BatchUpdatePlacementsResponse: + Response object for ``BatchUpdatePlacements`` method. + """ + + http_options = ( + _BasePlacementServiceRestTransport._BaseBatchUpdatePlacements._get_http_options() + ) + + request, metadata = self._interceptor.pre_batch_update_placements( + request, metadata + ) + transcoded_request = _BasePlacementServiceRestTransport._BaseBatchUpdatePlacements._get_transcoded_request( + http_options, request + ) + + body = _BasePlacementServiceRestTransport._BaseBatchUpdatePlacements._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BasePlacementServiceRestTransport._BaseBatchUpdatePlacements._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.PlacementServiceClient.BatchUpdatePlacements", + extra={ + "serviceName": "google.ads.admanager.v1.PlacementService", + "rpcName": "BatchUpdatePlacements", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + PlacementServiceRestTransport._BatchUpdatePlacements._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = placement_service.BatchUpdatePlacementsResponse() + pb_resp = placement_service.BatchUpdatePlacementsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_update_placements(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_update_placements_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + placement_service.BatchUpdatePlacementsResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.PlacementServiceClient.batch_update_placements", + extra={ + "serviceName": "google.ads.admanager.v1.PlacementService", + "rpcName": "BatchUpdatePlacements", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _CreatePlacement( + _BasePlacementServiceRestTransport._BaseCreatePlacement, + PlacementServiceRestStub, + ): + def __hash__(self): + return hash("PlacementServiceRestTransport.CreatePlacement") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: placement_service.CreatePlacementRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> placement_messages.Placement: + r"""Call the create placement method over HTTP. + + Args: + request (~.placement_service.CreatePlacementRequest): + The request object. Request object for ``CreatePlacement`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.placement_messages.Placement: + The ``Placement`` resource. + """ + + http_options = ( + _BasePlacementServiceRestTransport._BaseCreatePlacement._get_http_options() + ) + + request, metadata = self._interceptor.pre_create_placement( + request, metadata + ) + transcoded_request = _BasePlacementServiceRestTransport._BaseCreatePlacement._get_transcoded_request( + http_options, request + ) + + body = _BasePlacementServiceRestTransport._BaseCreatePlacement._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BasePlacementServiceRestTransport._BaseCreatePlacement._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.PlacementServiceClient.CreatePlacement", + extra={ + "serviceName": "google.ads.admanager.v1.PlacementService", + "rpcName": "CreatePlacement", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = PlacementServiceRestTransport._CreatePlacement._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = placement_messages.Placement() + pb_resp = placement_messages.Placement.pb(resp) - 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 ``channel`` 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 ``channel`` is provided. - client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client - certificate to configure mutual TLS HTTP channel. It is ignored - if ``channel`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you are developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - url_scheme: the protocol scheme for the API endpoint. Normally - "https", but for testing or local servers, - "http" can be specified. - """ - # Run the base constructor - # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. - # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the - # credentials object - super().__init__( - host=host, - credentials=credentials, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - url_scheme=url_scheme, - api_audience=api_audience, - ) - self._session = AuthorizedSession( - self._credentials, default_host=self.DEFAULT_HOST - ) - if client_cert_source_for_mtls: - self._session.configure_mtls_channel(client_cert_source_for_mtls) - self._interceptor = interceptor or PlacementServiceRestInterceptor() - self._prep_wrapped_messages(client_info) + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_placement(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_placement_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = placement_messages.Placement.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.PlacementServiceClient.create_placement", + extra={ + "serviceName": "google.ads.admanager.v1.PlacementService", + "rpcName": "CreatePlacement", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp class _GetPlacement( _BasePlacementServiceRestTransport._BaseGetPlacement, PlacementServiceRestStub @@ -599,6 +1965,224 @@ def __call__( ) return resp + class _UpdatePlacement( + _BasePlacementServiceRestTransport._BaseUpdatePlacement, + PlacementServiceRestStub, + ): + def __hash__(self): + return hash("PlacementServiceRestTransport.UpdatePlacement") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: placement_service.UpdatePlacementRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> placement_messages.Placement: + r"""Call the update placement method over HTTP. + + Args: + request (~.placement_service.UpdatePlacementRequest): + The request object. Request object for ``UpdatePlacement`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.placement_messages.Placement: + The ``Placement`` resource. + """ + + http_options = ( + _BasePlacementServiceRestTransport._BaseUpdatePlacement._get_http_options() + ) + + request, metadata = self._interceptor.pre_update_placement( + request, metadata + ) + transcoded_request = _BasePlacementServiceRestTransport._BaseUpdatePlacement._get_transcoded_request( + http_options, request + ) + + body = _BasePlacementServiceRestTransport._BaseUpdatePlacement._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BasePlacementServiceRestTransport._BaseUpdatePlacement._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.PlacementServiceClient.UpdatePlacement", + extra={ + "serviceName": "google.ads.admanager.v1.PlacementService", + "rpcName": "UpdatePlacement", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = PlacementServiceRestTransport._UpdatePlacement._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = placement_messages.Placement() + pb_resp = placement_messages.Placement.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_update_placement(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_placement_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = placement_messages.Placement.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.PlacementServiceClient.update_placement", + extra={ + "serviceName": "google.ads.admanager.v1.PlacementService", + "rpcName": "UpdatePlacement", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def batch_activate_placements( + self, + ) -> Callable[ + [placement_service.BatchActivatePlacementsRequest], + placement_service.BatchActivatePlacementsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchActivatePlacements(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_archive_placements( + self, + ) -> Callable[ + [placement_service.BatchArchivePlacementsRequest], + placement_service.BatchArchivePlacementsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchArchivePlacements(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_create_placements( + self, + ) -> Callable[ + [placement_service.BatchCreatePlacementsRequest], + placement_service.BatchCreatePlacementsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchCreatePlacements(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_deactivate_placements( + self, + ) -> Callable[ + [placement_service.BatchDeactivatePlacementsRequest], + placement_service.BatchDeactivatePlacementsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchDeactivatePlacements(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_update_placements( + self, + ) -> Callable[ + [placement_service.BatchUpdatePlacementsRequest], + placement_service.BatchUpdatePlacementsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchUpdatePlacements(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_placement( + self, + ) -> Callable[ + [placement_service.CreatePlacementRequest], placement_messages.Placement + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreatePlacement(self._session, self._host, self._interceptor) # type: ignore + @property def get_placement( self, @@ -620,6 +2204,16 @@ def list_placements( # In C++ this would require a dynamic_cast return self._ListPlacements(self._session, self._host, self._interceptor) # type: ignore + @property + def update_placement( + self, + ) -> Callable[ + [placement_service.UpdatePlacementRequest], placement_messages.Placement + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdatePlacement(self._session, self._host, self._interceptor) # type: ignore + @property def get_operation(self): return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/placement_service/transports/rest_base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/placement_service/transports/rest_base.py index c9d7a6f3392d..765ec80efc74 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/services/placement_service/transports/rest_base.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/placement_service/transports/rest_base.py @@ -88,6 +88,348 @@ def __init__( api_audience=api_audience, ) + class _BaseBatchActivatePlacements: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/placements:batchActivate", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = placement_service.BatchActivatePlacementsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BasePlacementServiceRestTransport._BaseBatchActivatePlacements._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseBatchArchivePlacements: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/placements:batchArchive", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = placement_service.BatchArchivePlacementsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BasePlacementServiceRestTransport._BaseBatchArchivePlacements._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseBatchCreatePlacements: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/placements:batchCreate", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = placement_service.BatchCreatePlacementsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BasePlacementServiceRestTransport._BaseBatchCreatePlacements._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseBatchDeactivatePlacements: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/placements:batchDeactivate", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = placement_service.BatchDeactivatePlacementsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BasePlacementServiceRestTransport._BaseBatchDeactivatePlacements._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseBatchUpdatePlacements: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/placements:batchUpdate", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = placement_service.BatchUpdatePlacementsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BasePlacementServiceRestTransport._BaseBatchUpdatePlacements._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseCreatePlacement: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/placements", + "body": "placement", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = placement_service.CreatePlacementRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BasePlacementServiceRestTransport._BaseCreatePlacement._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + class _BaseGetPlacement: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") @@ -182,6 +524,65 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params + class _BaseUpdatePlacement: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "updateMask": {}, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v1/{placement.name=networks/*/placements/*}", + "body": "placement", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = placement_service.UpdatePlacementRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BasePlacementServiceRestTransport._BaseUpdatePlacement._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + class _BaseGetOperation: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/private_auction_deal_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/private_auction_deal_service/client.py index 0333d446a194..aea1d9aae2a3 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/services/private_auction_deal_service/client.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/private_auction_deal_service/client.py @@ -221,6 +221,45 @@ def parse_ad_unit_path(path: str) -> Dict[str, str]: m = re.match(r"^networks/(?P.+?)/adUnits/(?P.+?)$", path) return m.groupdict() if m else {} + @staticmethod + def application_path( + network_code: str, + application: str, + ) -> str: + """Returns a fully-qualified application string.""" + return "networks/{network_code}/applications/{application}".format( + network_code=network_code, + application=application, + ) + + @staticmethod + def parse_application_path(path: str) -> Dict[str, str]: + """Parses a application path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/applications/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def audience_segment_path( + network_code: str, + audience_segment: str, + ) -> str: + """Returns a fully-qualified audience_segment string.""" + return "networks/{network_code}/audienceSegments/{audience_segment}".format( + network_code=network_code, + audience_segment=audience_segment, + ) + + @staticmethod + def parse_audience_segment_path(path: str) -> Dict[str, str]: + """Parses a audience_segment path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/audienceSegments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def bandwidth_group_path( network_code: str, @@ -241,6 +280,102 @@ def parse_bandwidth_group_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def browser_path( + network_code: str, + browser: str, + ) -> str: + """Returns a fully-qualified browser string.""" + return "networks/{network_code}/browsers/{browser}".format( + network_code=network_code, + browser=browser, + ) + + @staticmethod + def parse_browser_path(path: str) -> Dict[str, str]: + """Parses a browser path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/browsers/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def browser_language_path( + network_code: str, + browser_language: str, + ) -> str: + """Returns a fully-qualified browser_language string.""" + return "networks/{network_code}/browserLanguages/{browser_language}".format( + network_code=network_code, + browser_language=browser_language, + ) + + @staticmethod + def parse_browser_language_path(path: str) -> Dict[str, str]: + """Parses a browser_language path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/browserLanguages/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def cms_metadata_value_path( + network_code: str, + cms_metadata_value: str, + ) -> str: + """Returns a fully-qualified cms_metadata_value string.""" + return "networks/{network_code}/cmsMetadataValues/{cms_metadata_value}".format( + network_code=network_code, + cms_metadata_value=cms_metadata_value, + ) + + @staticmethod + def parse_cms_metadata_value_path(path: str) -> Dict[str, str]: + """Parses a cms_metadata_value path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/cmsMetadataValues/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def content_path( + network_code: str, + content: str, + ) -> str: + """Returns a fully-qualified content string.""" + return "networks/{network_code}/content/{content}".format( + network_code=network_code, + content=content, + ) + + @staticmethod + def parse_content_path(path: str) -> Dict[str, str]: + """Parses a content path into its component segments.""" + m = re.match(r"^networks/(?P.+?)/content/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def content_bundle_path( + network_code: str, + content_bundle: str, + ) -> str: + """Returns a fully-qualified content_bundle string.""" + return "networks/{network_code}/contentBundles/{content_bundle}".format( + network_code=network_code, + content_bundle=content_bundle, + ) + + @staticmethod + def parse_content_bundle_path(path: str) -> Dict[str, str]: + """Parses a content_bundle path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/contentBundles/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def custom_targeting_key_path( network_code: str, @@ -283,6 +418,26 @@ def parse_custom_targeting_value_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def device_capability_path( + network_code: str, + device_capability: str, + ) -> str: + """Returns a fully-qualified device_capability string.""" + return "networks/{network_code}/deviceCapabilities/{device_capability}".format( + network_code=network_code, + device_capability=device_capability, + ) + + @staticmethod + def parse_device_capability_path(path: str) -> Dict[str, str]: + """Parses a device_capability path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/deviceCapabilities/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def device_category_path( network_code: str, @@ -303,6 +458,28 @@ def parse_device_category_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def device_manufacturer_path( + network_code: str, + device_manufacturer: str, + ) -> str: + """Returns a fully-qualified device_manufacturer string.""" + return ( + "networks/{network_code}/deviceManufacturers/{device_manufacturer}".format( + network_code=network_code, + device_manufacturer=device_manufacturer, + ) + ) + + @staticmethod + def parse_device_manufacturer_path(path: str) -> Dict[str, str]: + """Parses a device_manufacturer path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/deviceManufacturers/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def geo_target_path( network_code: str, @@ -322,6 +499,66 @@ def parse_geo_target_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def mobile_carrier_path( + network_code: str, + mobile_carrier: str, + ) -> str: + """Returns a fully-qualified mobile_carrier string.""" + return "networks/{network_code}/mobileCarriers/{mobile_carrier}".format( + network_code=network_code, + mobile_carrier=mobile_carrier, + ) + + @staticmethod + def parse_mobile_carrier_path(path: str) -> Dict[str, str]: + """Parses a mobile_carrier path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/mobileCarriers/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def mobile_device_path( + network_code: str, + mobile_device: str, + ) -> str: + """Returns a fully-qualified mobile_device string.""" + return "networks/{network_code}/mobileDevices/{mobile_device}".format( + network_code=network_code, + mobile_device=mobile_device, + ) + + @staticmethod + def parse_mobile_device_path(path: str) -> Dict[str, str]: + """Parses a mobile_device path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/mobileDevices/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def mobile_device_submodel_path( + network_code: str, + mobile_device_submodel: str, + ) -> str: + """Returns a fully-qualified mobile_device_submodel string.""" + return "networks/{network_code}/mobileDeviceSubmodels/{mobile_device_submodel}".format( + network_code=network_code, + mobile_device_submodel=mobile_device_submodel, + ) + + @staticmethod + def parse_mobile_device_submodel_path(path: str) -> Dict[str, str]: + """Parses a mobile_device_submodel path into its component segments.""" + m = re.match( + r"^networks/(?P.+?)/mobileDeviceSubmodels/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def network_path( network_code: str, diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/report_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/report_service/client.py index 0c4821d1b5b4..916e555dcf47 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/services/report_service/client.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/report_service/client.py @@ -68,7 +68,11 @@ from google.protobuf import timestamp_pb2 # type: ignore from google.ads.admanager_v1.services.report_service import pagers -from google.ads.admanager_v1.types import report_messages, report_service +from google.ads.admanager_v1.types import ( + report_definition, + report_messages, + report_service, +) from .transports.base import DEFAULT_CLIENT_INFO, ReportServiceTransport from .transports.rest import ReportServiceRestTransport @@ -978,7 +982,7 @@ def sample_create_report(): report = admanager_v1.Report() report.report_definition.dimensions = ['CUSTOM_DIMENSION_9_VALUE'] report.report_definition.metrics = ['YIELD_GROUP_SUCCESSFUL_RESPONSES'] - report.report_definition.report_type = "HISTORICAL" + report.report_definition.report_type = "AD_SPEED" request = admanager_v1.CreateReportRequest( parent="parent_value", @@ -1097,7 +1101,7 @@ def sample_update_report(): report = admanager_v1.Report() report.report_definition.dimensions = ['CUSTOM_DIMENSION_9_VALUE'] report.report_definition.metrics = ['YIELD_GROUP_SUCCESSFUL_RESPONSES'] - report.report_definition.report_type = "HISTORICAL" + report.report_definition.report_type = "AD_SPEED" request = admanager_v1.UpdateReportRequest( report=report, @@ -1196,7 +1200,7 @@ def run_report( metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> operation.Operation: r"""Initiates the execution of an existing report asynchronously. - Users can get the report by polling this operation via + Users can get the report by polling this operation using ``OperationsService.GetOperation``. Poll every 5 seconds initially, with an exponential backoff. Once a report is complete, the operation will contain a ``RunReportResponse`` in diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/report_service/pagers.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/report_service/pagers.py index 4c85518405d1..b37c4e04b280 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/services/report_service/pagers.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/report_service/pagers.py @@ -185,7 +185,7 @@ def pages(self) -> Iterator[report_service.FetchReportResultRowsResponse]: ) yield self._response - def __iter__(self) -> Iterator[report_messages.Report.DataTable.Row]: + def __iter__(self) -> Iterator[report_messages.ReportDataTable.Row]: for page in self.pages: yield from page.rows diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/__init__.py new file mode 100644 index 000000000000..9c16df2c709e --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 SiteServiceClient + +__all__ = ("SiteServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/client.py new file mode 100644 index 000000000000..b6040ba1e6ff --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/client.py @@ -0,0 +1,1743 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +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.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version + +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.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + +from google.ads.admanager_v1.services.site_service import pagers +from google.ads.admanager_v1.types import site_enums, site_messages, site_service + +from .transports.base import DEFAULT_CLIENT_INFO, SiteServiceTransport +from .transports.rest import SiteServiceRestTransport + + +class SiteServiceClientMeta(type): + """Metaclass for the SiteService 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[SiteServiceTransport]] + _transport_registry["rest"] = SiteServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[SiteServiceTransport]: + """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 SiteServiceClient(metaclass=SiteServiceClientMeta): + """Provides methods for handling ``Site`` objects.""" + + @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 = "admanager.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "admanager.{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: + SiteServiceClient: 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: + SiteServiceClient: 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) -> SiteServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SiteServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def network_path( + network_code: str, + ) -> str: + """Returns a fully-qualified network string.""" + return "networks/{network_code}".format( + network_code=network_code, + ) + + @staticmethod + def parse_network_path(path: str) -> Dict[str, str]: + """Parses a network path into its component segments.""" + m = re.match(r"^networks/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def site_path( + network_code: str, + site: str, + ) -> str: + """Returns a fully-qualified site string.""" + return "networks/{network_code}/sites/{site}".format( + network_code=network_code, + site=site, + ) + + @staticmethod + def parse_site_path(path: str) -> Dict[str, str]: + """Parses a site path into its component segments.""" + m = re.match(r"^networks/(?P.+?)/sites/(?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 = SiteServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = SiteServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = SiteServiceClient._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 = SiteServiceClient._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, SiteServiceTransport, Callable[..., SiteServiceTransport]] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the site 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,SiteServiceTransport,Callable[..., SiteServiceTransport]]]): + 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 SiteServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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, + ) = SiteServiceClient._read_environment_variables() + self._client_cert_source = SiteServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = SiteServiceClient._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, SiteServiceTransport) + if transport_provided: + # transport is a SiteServiceTransport 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(SiteServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = self._api_endpoint or SiteServiceClient._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[SiteServiceTransport], Callable[..., SiteServiceTransport] + ] = ( + SiteServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., SiteServiceTransport], 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.admanager_v1.SiteServiceClient`.", + extra={ + "serviceName": "google.ads.admanager.v1.SiteService", + "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.admanager.v1.SiteService", + "credentialsType": None, + }, + ) + + def get_site( + self, + request: Optional[Union[site_service.GetSiteRequest, dict]] = None, + *, + 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]]] = (), + ) -> site_messages.Site: + r"""API to retrieve a ``Site`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_get_site(): + # Create a client + client = admanager_v1.SiteServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetSiteRequest( + name="name_value", + ) + + # Make the request + response = client.get_site(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.GetSiteRequest, dict]): + The request object. Request object for ``GetSite`` method. + name (str): + Required. The resource name of the Site. Format: + ``networks/{network_code}/sites/{site_id}`` + + This corresponds to the ``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.admanager_v1.types.Site: + A Site represents a domain owned or + represented by a network. For a parent + network managing other networks as part + of Multiple Customer Management "Manage + Inventory" model, it could be the + child's domain. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, site_service.GetSiteRequest): + request = site_service.GetSiteRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_site] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_sites( + self, + request: Optional[Union[site_service.ListSitesRequest, dict]] = None, + *, + parent: 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.ListSitesPager: + r"""API to retrieve a list of ``Site`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_list_sites(): + # Create a client + client = admanager_v1.SiteServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListSitesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_sites(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.ListSitesRequest, dict]): + The request object. Request object for ``ListSites`` method. + parent (str): + Required. The parent, which owns this collection of + Sites. Format: ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.services.site_service.pagers.ListSitesPager: + Response object for ListSitesRequest containing matching + Site objects. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, site_service.ListSitesRequest): + request = site_service.ListSitesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_sites] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.ListSitesPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def create_site( + self, + request: Optional[Union[site_service.CreateSiteRequest, dict]] = None, + *, + parent: Optional[str] = None, + site: Optional[site_messages.Site] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> site_messages.Site: + r"""API to create a ``Site`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_create_site(): + # Create a client + client = admanager_v1.SiteServiceClient() + + # Initialize request argument(s) + request = admanager_v1.CreateSiteRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_site(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.CreateSiteRequest, dict]): + The request object. Request object for ``CreateSite`` method. + parent (str): + Required. The parent resource where this ``Site`` will + be created. Format: ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + site (google.ads.admanager_v1.types.Site): + Required. The ``Site`` to create. + This corresponds to the ``site`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.Site: + A Site represents a domain owned or + represented by a network. For a parent + network managing other networks as part + of Multiple Customer Management "Manage + Inventory" model, it could be the + child's domain. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, site] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, site_service.CreateSiteRequest): + request = site_service.CreateSiteRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if site is not None: + request.site = site + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_site] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def batch_create_sites( + self, + request: Optional[Union[site_service.BatchCreateSitesRequest, dict]] = None, + *, + parent: Optional[str] = None, + requests: Optional[MutableSequence[site_service.CreateSiteRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> site_service.BatchCreateSitesResponse: + r"""API to batch create ``Site`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_batch_create_sites(): + # Create a client + client = admanager_v1.SiteServiceClient() + + # Initialize request argument(s) + requests = admanager_v1.CreateSiteRequest() + requests.parent = "parent_value" + + request = admanager_v1.BatchCreateSitesRequest( + parent="parent_value", + requests=requests, + ) + + # Make the request + response = client.batch_create_sites(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.BatchCreateSitesRequest, dict]): + The request object. Request object for ``BatchCreateSites`` method. + parent (str): + Required. The parent resource where ``Sites`` will be + created. Format: ``networks/{network_code}`` The parent + field in the CreateSiteRequest must match this field. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + requests (MutableSequence[google.ads.admanager_v1.types.CreateSiteRequest]): + Required. The ``Site`` objects to create. A maximum of + 100 objects can be created in a batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.BatchCreateSitesResponse: + Response object for BatchCreateSites method. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, requests] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, site_service.BatchCreateSitesRequest): + request = site_service.BatchCreateSitesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_create_sites] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe 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_site( + self, + request: Optional[Union[site_service.UpdateSiteRequest, dict]] = None, + *, + site: Optional[site_messages.Site] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> site_messages.Site: + r"""API to update a ``Site`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_update_site(): + # Create a client + client = admanager_v1.SiteServiceClient() + + # Initialize request argument(s) + request = admanager_v1.UpdateSiteRequest( + ) + + # Make the request + response = client.update_site(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.UpdateSiteRequest, dict]): + The request object. Request object for ``UpdateSite`` method. + site (google.ads.admanager_v1.types.Site): + Required. The ``Site`` to update. + + The ``Site``'s ``name`` is used to identify the ``Site`` + to update. + + This corresponds to the ``site`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Required. The list of fields to + update. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.Site: + A Site represents a domain owned or + represented by a network. For a parent + network managing other networks as part + of Multiple Customer Management "Manage + Inventory" model, it could be the + child's domain. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [site, update_mask] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, site_service.UpdateSiteRequest): + request = site_service.UpdateSiteRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if site is not None: + request.site = site + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_site] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("site.name", request.site.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 batch_update_sites( + self, + request: Optional[Union[site_service.BatchUpdateSitesRequest, dict]] = None, + *, + parent: Optional[str] = None, + requests: Optional[MutableSequence[site_service.UpdateSiteRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> site_service.BatchUpdateSitesResponse: + r"""API to batch update ``Site`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_batch_update_sites(): + # Create a client + client = admanager_v1.SiteServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchUpdateSitesRequest( + parent="parent_value", + ) + + # Make the request + response = client.batch_update_sites(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.BatchUpdateSitesRequest, dict]): + The request object. Request object for ``BatchUpdateSites`` method. + parent (str): + Required. The parent resource where ``Sites`` will be + updated. Format: ``networks/{network_code}`` The parent + field in the UpdateSiteRequest must match this field. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + requests (MutableSequence[google.ads.admanager_v1.types.UpdateSiteRequest]): + Required. The ``Site`` objects to update. A maximum of + 100 objects can be updated in a batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.BatchUpdateSitesResponse: + Response object for BatchUpdateSites method. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, requests] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, site_service.BatchUpdateSitesRequest): + request = site_service.BatchUpdateSitesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_update_sites] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def batch_deactivate_sites( + self, + request: Optional[Union[site_service.BatchDeactivateSitesRequest, dict]] = None, + *, + parent: Optional[str] = None, + names: 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]]] = (), + ) -> site_service.BatchDeactivateSitesResponse: + r"""Deactivates a list of ``Site`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_batch_deactivate_sites(): + # Create a client + client = admanager_v1.SiteServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchDeactivateSitesRequest( + parent="parent_value", + names=['names_value1', 'names_value2'], + ) + + # Make the request + response = client.batch_deactivate_sites(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.BatchDeactivateSitesRequest, dict]): + The request object. Request message for ``BatchDeactivateSites`` method. + parent (str): + Required. Format: ``networks/{network_code}`` + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + names (MutableSequence[str]): + Required. The resource names of the ``Site`` objects to + deactivate. + + This corresponds to the ``names`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.BatchDeactivateSitesResponse: + Response object for BatchDeactivateSites method. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, names] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, site_service.BatchDeactivateSitesRequest): + request = site_service.BatchDeactivateSitesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if names is not None: + request.names = names + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_deactivate_sites] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def batch_submit_sites_for_approval( + self, + request: Optional[ + Union[site_service.BatchSubmitSitesForApprovalRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + names: 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]]] = (), + ) -> site_service.BatchSubmitSitesForApprovalResponse: + r"""Submits a list of ``Site`` objects for approval. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_batch_submit_sites_for_approval(): + # Create a client + client = admanager_v1.SiteServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchSubmitSitesForApprovalRequest( + parent="parent_value", + names=['names_value1', 'names_value2'], + ) + + # Make the request + response = client.batch_submit_sites_for_approval(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.BatchSubmitSitesForApprovalRequest, dict]): + The request object. Request message for ``BatchSubmitSitesForApproval`` + method. + parent (str): + Required. Format: ``networks/{network_code}`` + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + names (MutableSequence[str]): + Required. The resource names of the ``Site`` objects to + submit for approval. + + This corresponds to the ``names`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.BatchSubmitSitesForApprovalResponse: + Response object for BatchSubmitSitesForApproval method. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, names] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, site_service.BatchSubmitSitesForApprovalRequest): + request = site_service.BatchSubmitSitesForApprovalRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if names is not None: + request.names = names + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.batch_submit_sites_for_approval + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe 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) -> "SiteServiceClient": + 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() + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("SiteServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/pagers.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/pagers.py new file mode 100644 index 000000000000..dea236c7bd2d --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/pagers.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +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 + +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.admanager_v1.types import site_messages, site_service + + +class ListSitesPager: + """A pager for iterating through ``list_sites`` requests. + + This class thinly wraps an initial + :class:`google.ads.admanager_v1.types.ListSitesResponse` object, and + provides an ``__iter__`` method to iterate through its + ``sites`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListSites`` requests and continue to iterate + through the ``sites`` field on the + corresponding responses. + + All the usual :class:`google.ads.admanager_v1.types.ListSitesResponse` + 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[..., site_service.ListSitesResponse], + request: site_service.ListSitesRequest, + response: site_service.ListSitesResponse, + *, + 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.admanager_v1.types.ListSitesRequest): + The initial request object. + response (google.ads.admanager_v1.types.ListSitesResponse): + 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 = site_service.ListSitesRequest(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[site_service.ListSitesResponse]: + 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[site_messages.Site]: + for page in self.pages: + yield from page.sites + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/transports/README.rst b/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/transports/README.rst new file mode 100644 index 000000000000..765c3011c0b4 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`SiteServiceTransport` is the ABC for all transports. +- public child `SiteServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `SiteServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseSiteServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `SiteServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/transports/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/transports/__init__.py new file mode 100644 index 000000000000..ff7935f340d5 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/transports/__init__.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 typing import Dict, Type + +from .base import SiteServiceTransport +from .rest import SiteServiceRestInterceptor, SiteServiceRestTransport + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[SiteServiceTransport]] +_transport_registry["rest"] = SiteServiceRestTransport + +__all__ = ( + "SiteServiceTransport", + "SiteServiceRestTransport", + "SiteServiceRestInterceptor", +) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/transports/base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/transports/base.py new file mode 100644 index 000000000000..60eebd234576 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/transports/base.py @@ -0,0 +1,293 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version +from google.ads.admanager_v1.types import site_messages, site_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 SiteServiceTransport(abc.ABC): + """Abstract transport class for SiteService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/admanager",) + + DEFAULT_HOST: str = "admanager.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: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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_site: gapic_v1.method.wrap_method( + self.get_site, + default_timeout=None, + client_info=client_info, + ), + self.list_sites: gapic_v1.method.wrap_method( + self.list_sites, + default_timeout=None, + client_info=client_info, + ), + self.create_site: gapic_v1.method.wrap_method( + self.create_site, + default_timeout=None, + client_info=client_info, + ), + self.batch_create_sites: gapic_v1.method.wrap_method( + self.batch_create_sites, + default_timeout=None, + client_info=client_info, + ), + self.update_site: gapic_v1.method.wrap_method( + self.update_site, + default_timeout=None, + client_info=client_info, + ), + self.batch_update_sites: gapic_v1.method.wrap_method( + self.batch_update_sites, + default_timeout=None, + client_info=client_info, + ), + self.batch_deactivate_sites: gapic_v1.method.wrap_method( + self.batch_deactivate_sites, + default_timeout=None, + client_info=client_info, + ), + self.batch_submit_sites_for_approval: gapic_v1.method.wrap_method( + self.batch_submit_sites_for_approval, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + 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_site( + self, + ) -> Callable[ + [site_service.GetSiteRequest], + Union[site_messages.Site, Awaitable[site_messages.Site]], + ]: + raise NotImplementedError() + + @property + def list_sites( + self, + ) -> Callable[ + [site_service.ListSitesRequest], + Union[ + site_service.ListSitesResponse, Awaitable[site_service.ListSitesResponse] + ], + ]: + raise NotImplementedError() + + @property + def create_site( + self, + ) -> Callable[ + [site_service.CreateSiteRequest], + Union[site_messages.Site, Awaitable[site_messages.Site]], + ]: + raise NotImplementedError() + + @property + def batch_create_sites( + self, + ) -> Callable[ + [site_service.BatchCreateSitesRequest], + Union[ + site_service.BatchCreateSitesResponse, + Awaitable[site_service.BatchCreateSitesResponse], + ], + ]: + raise NotImplementedError() + + @property + def update_site( + self, + ) -> Callable[ + [site_service.UpdateSiteRequest], + Union[site_messages.Site, Awaitable[site_messages.Site]], + ]: + raise NotImplementedError() + + @property + def batch_update_sites( + self, + ) -> Callable[ + [site_service.BatchUpdateSitesRequest], + Union[ + site_service.BatchUpdateSitesResponse, + Awaitable[site_service.BatchUpdateSitesResponse], + ], + ]: + raise NotImplementedError() + + @property + def batch_deactivate_sites( + self, + ) -> Callable[ + [site_service.BatchDeactivateSitesRequest], + Union[ + site_service.BatchDeactivateSitesResponse, + Awaitable[site_service.BatchDeactivateSitesResponse], + ], + ]: + raise NotImplementedError() + + @property + def batch_submit_sites_for_approval( + self, + ) -> Callable[ + [site_service.BatchSubmitSitesForApprovalRequest], + Union[ + site_service.BatchSubmitSitesForApprovalResponse, + Awaitable[site_service.BatchSubmitSitesForApprovalResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("SiteServiceTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/transports/rest.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/transports/rest.py new file mode 100644 index 000000000000..845aa0aae342 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/transports/rest.py @@ -0,0 +1,2113 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.ads.admanager_v1.types import site_messages, site_service + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseSiteServiceRestTransport + +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 = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class SiteServiceRestInterceptor: + """Interceptor for SiteService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the SiteServiceRestTransport. + + .. code-block:: python + class MyCustomSiteServiceInterceptor(SiteServiceRestInterceptor): + def pre_batch_create_sites(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_create_sites(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_deactivate_sites(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_deactivate_sites(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_submit_sites_for_approval(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_submit_sites_for_approval(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_update_sites(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_update_sites(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_site(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_site(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_site(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_site(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_sites(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_sites(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_site(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_site(self, response): + logging.log(f"Received response: {response}") + return response + + transport = SiteServiceRestTransport(interceptor=MyCustomSiteServiceInterceptor()) + client = SiteServiceClient(transport=transport) + + + """ + + def pre_batch_create_sites( + self, + request: site_service.BatchCreateSitesRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + site_service.BatchCreateSitesRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for batch_create_sites + + Override in a subclass to manipulate the request or metadata + before they are sent to the SiteService server. + """ + return request, metadata + + def post_batch_create_sites( + self, response: site_service.BatchCreateSitesResponse + ) -> site_service.BatchCreateSitesResponse: + """Post-rpc interceptor for batch_create_sites + + DEPRECATED. Please use the `post_batch_create_sites_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the SiteService server but before + it is returned to user code. This `post_batch_create_sites` interceptor runs + before the `post_batch_create_sites_with_metadata` interceptor. + """ + return response + + def post_batch_create_sites_with_metadata( + self, + response: site_service.BatchCreateSitesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + site_service.BatchCreateSitesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for batch_create_sites + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteService server but before it is returned to user code. + + We recommend only using this `post_batch_create_sites_with_metadata` + interceptor in new development instead of the `post_batch_create_sites` interceptor. + When both interceptors are used, this `post_batch_create_sites_with_metadata` interceptor runs after the + `post_batch_create_sites` interceptor. The (possibly modified) response returned by + `post_batch_create_sites` will be passed to + `post_batch_create_sites_with_metadata`. + """ + return response, metadata + + def pre_batch_deactivate_sites( + self, + request: site_service.BatchDeactivateSitesRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + site_service.BatchDeactivateSitesRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for batch_deactivate_sites + + Override in a subclass to manipulate the request or metadata + before they are sent to the SiteService server. + """ + return request, metadata + + def post_batch_deactivate_sites( + self, response: site_service.BatchDeactivateSitesResponse + ) -> site_service.BatchDeactivateSitesResponse: + """Post-rpc interceptor for batch_deactivate_sites + + DEPRECATED. Please use the `post_batch_deactivate_sites_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the SiteService server but before + it is returned to user code. This `post_batch_deactivate_sites` interceptor runs + before the `post_batch_deactivate_sites_with_metadata` interceptor. + """ + return response + + def post_batch_deactivate_sites_with_metadata( + self, + response: site_service.BatchDeactivateSitesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + site_service.BatchDeactivateSitesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for batch_deactivate_sites + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteService server but before it is returned to user code. + + We recommend only using this `post_batch_deactivate_sites_with_metadata` + interceptor in new development instead of the `post_batch_deactivate_sites` interceptor. + When both interceptors are used, this `post_batch_deactivate_sites_with_metadata` interceptor runs after the + `post_batch_deactivate_sites` interceptor. The (possibly modified) response returned by + `post_batch_deactivate_sites` will be passed to + `post_batch_deactivate_sites_with_metadata`. + """ + return response, metadata + + def pre_batch_submit_sites_for_approval( + self, + request: site_service.BatchSubmitSitesForApprovalRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + site_service.BatchSubmitSitesForApprovalRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for batch_submit_sites_for_approval + + Override in a subclass to manipulate the request or metadata + before they are sent to the SiteService server. + """ + return request, metadata + + def post_batch_submit_sites_for_approval( + self, response: site_service.BatchSubmitSitesForApprovalResponse + ) -> site_service.BatchSubmitSitesForApprovalResponse: + """Post-rpc interceptor for batch_submit_sites_for_approval + + DEPRECATED. Please use the `post_batch_submit_sites_for_approval_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the SiteService server but before + it is returned to user code. This `post_batch_submit_sites_for_approval` interceptor runs + before the `post_batch_submit_sites_for_approval_with_metadata` interceptor. + """ + return response + + def post_batch_submit_sites_for_approval_with_metadata( + self, + response: site_service.BatchSubmitSitesForApprovalResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + site_service.BatchSubmitSitesForApprovalResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for batch_submit_sites_for_approval + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteService server but before it is returned to user code. + + We recommend only using this `post_batch_submit_sites_for_approval_with_metadata` + interceptor in new development instead of the `post_batch_submit_sites_for_approval` interceptor. + When both interceptors are used, this `post_batch_submit_sites_for_approval_with_metadata` interceptor runs after the + `post_batch_submit_sites_for_approval` interceptor. The (possibly modified) response returned by + `post_batch_submit_sites_for_approval` will be passed to + `post_batch_submit_sites_for_approval_with_metadata`. + """ + return response, metadata + + def pre_batch_update_sites( + self, + request: site_service.BatchUpdateSitesRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + site_service.BatchUpdateSitesRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for batch_update_sites + + Override in a subclass to manipulate the request or metadata + before they are sent to the SiteService server. + """ + return request, metadata + + def post_batch_update_sites( + self, response: site_service.BatchUpdateSitesResponse + ) -> site_service.BatchUpdateSitesResponse: + """Post-rpc interceptor for batch_update_sites + + DEPRECATED. Please use the `post_batch_update_sites_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the SiteService server but before + it is returned to user code. This `post_batch_update_sites` interceptor runs + before the `post_batch_update_sites_with_metadata` interceptor. + """ + return response + + def post_batch_update_sites_with_metadata( + self, + response: site_service.BatchUpdateSitesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + site_service.BatchUpdateSitesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for batch_update_sites + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteService server but before it is returned to user code. + + We recommend only using this `post_batch_update_sites_with_metadata` + interceptor in new development instead of the `post_batch_update_sites` interceptor. + When both interceptors are used, this `post_batch_update_sites_with_metadata` interceptor runs after the + `post_batch_update_sites` interceptor. The (possibly modified) response returned by + `post_batch_update_sites` will be passed to + `post_batch_update_sites_with_metadata`. + """ + return response, metadata + + def pre_create_site( + self, + request: site_service.CreateSiteRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[site_service.CreateSiteRequest, Sequence[Tuple[str, Union[str, bytes]]]]: + """Pre-rpc interceptor for create_site + + Override in a subclass to manipulate the request or metadata + before they are sent to the SiteService server. + """ + return request, metadata + + def post_create_site(self, response: site_messages.Site) -> site_messages.Site: + """Post-rpc interceptor for create_site + + DEPRECATED. Please use the `post_create_site_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the SiteService server but before + it is returned to user code. This `post_create_site` interceptor runs + before the `post_create_site_with_metadata` interceptor. + """ + return response + + def post_create_site_with_metadata( + self, + response: site_messages.Site, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[site_messages.Site, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_site + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteService server but before it is returned to user code. + + We recommend only using this `post_create_site_with_metadata` + interceptor in new development instead of the `post_create_site` interceptor. + When both interceptors are used, this `post_create_site_with_metadata` interceptor runs after the + `post_create_site` interceptor. The (possibly modified) response returned by + `post_create_site` will be passed to + `post_create_site_with_metadata`. + """ + return response, metadata + + def pre_get_site( + self, + request: site_service.GetSiteRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[site_service.GetSiteRequest, Sequence[Tuple[str, Union[str, bytes]]]]: + """Pre-rpc interceptor for get_site + + Override in a subclass to manipulate the request or metadata + before they are sent to the SiteService server. + """ + return request, metadata + + def post_get_site(self, response: site_messages.Site) -> site_messages.Site: + """Post-rpc interceptor for get_site + + DEPRECATED. Please use the `post_get_site_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the SiteService server but before + it is returned to user code. This `post_get_site` interceptor runs + before the `post_get_site_with_metadata` interceptor. + """ + return response + + def post_get_site_with_metadata( + self, + response: site_messages.Site, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[site_messages.Site, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_site + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteService server but before it is returned to user code. + + We recommend only using this `post_get_site_with_metadata` + interceptor in new development instead of the `post_get_site` interceptor. + When both interceptors are used, this `post_get_site_with_metadata` interceptor runs after the + `post_get_site` interceptor. The (possibly modified) response returned by + `post_get_site` will be passed to + `post_get_site_with_metadata`. + """ + return response, metadata + + def pre_list_sites( + self, + request: site_service.ListSitesRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[site_service.ListSitesRequest, Sequence[Tuple[str, Union[str, bytes]]]]: + """Pre-rpc interceptor for list_sites + + Override in a subclass to manipulate the request or metadata + before they are sent to the SiteService server. + """ + return request, metadata + + def post_list_sites( + self, response: site_service.ListSitesResponse + ) -> site_service.ListSitesResponse: + """Post-rpc interceptor for list_sites + + DEPRECATED. Please use the `post_list_sites_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the SiteService server but before + it is returned to user code. This `post_list_sites` interceptor runs + before the `post_list_sites_with_metadata` interceptor. + """ + return response + + def post_list_sites_with_metadata( + self, + response: site_service.ListSitesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[site_service.ListSitesResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_sites + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteService server but before it is returned to user code. + + We recommend only using this `post_list_sites_with_metadata` + interceptor in new development instead of the `post_list_sites` interceptor. + When both interceptors are used, this `post_list_sites_with_metadata` interceptor runs after the + `post_list_sites` interceptor. The (possibly modified) response returned by + `post_list_sites` will be passed to + `post_list_sites_with_metadata`. + """ + return response, metadata + + def pre_update_site( + self, + request: site_service.UpdateSiteRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[site_service.UpdateSiteRequest, Sequence[Tuple[str, Union[str, bytes]]]]: + """Pre-rpc interceptor for update_site + + Override in a subclass to manipulate the request or metadata + before they are sent to the SiteService server. + """ + return request, metadata + + def post_update_site(self, response: site_messages.Site) -> site_messages.Site: + """Post-rpc interceptor for update_site + + DEPRECATED. Please use the `post_update_site_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the SiteService server but before + it is returned to user code. This `post_update_site` interceptor runs + before the `post_update_site_with_metadata` interceptor. + """ + return response + + def post_update_site_with_metadata( + self, + response: site_messages.Site, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[site_messages.Site, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_site + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteService server but before it is returned to user code. + + We recommend only using this `post_update_site_with_metadata` + interceptor in new development instead of the `post_update_site` interceptor. + When both interceptors are used, this `post_update_site_with_metadata` interceptor runs after the + `post_update_site` interceptor. The (possibly modified) response returned by + `post_update_site` will be passed to + `post_update_site_with_metadata`. + """ + return response, metadata + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the SiteService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the SiteService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class SiteServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: SiteServiceRestInterceptor + + +class SiteServiceRestTransport(_BaseSiteServiceRestTransport): + """REST backend synchronous transport for SiteService. + + Provides methods for handling ``Site`` objects. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[SiteServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or SiteServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _BatchCreateSites( + _BaseSiteServiceRestTransport._BaseBatchCreateSites, SiteServiceRestStub + ): + def __hash__(self): + return hash("SiteServiceRestTransport.BatchCreateSites") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: site_service.BatchCreateSitesRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> site_service.BatchCreateSitesResponse: + r"""Call the batch create sites method over HTTP. + + Args: + request (~.site_service.BatchCreateSitesRequest): + The request object. Request object for ``BatchCreateSites`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.site_service.BatchCreateSitesResponse: + Response object for ``BatchCreateSites`` method. + """ + + http_options = ( + _BaseSiteServiceRestTransport._BaseBatchCreateSites._get_http_options() + ) + + request, metadata = self._interceptor.pre_batch_create_sites( + request, metadata + ) + transcoded_request = _BaseSiteServiceRestTransport._BaseBatchCreateSites._get_transcoded_request( + http_options, request + ) + + body = _BaseSiteServiceRestTransport._BaseBatchCreateSites._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseSiteServiceRestTransport._BaseBatchCreateSites._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.SiteServiceClient.BatchCreateSites", + extra={ + "serviceName": "google.ads.admanager.v1.SiteService", + "rpcName": "BatchCreateSites", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = SiteServiceRestTransport._BatchCreateSites._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = site_service.BatchCreateSitesResponse() + pb_resp = site_service.BatchCreateSitesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_create_sites(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_create_sites_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = site_service.BatchCreateSitesResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.SiteServiceClient.batch_create_sites", + extra={ + "serviceName": "google.ads.admanager.v1.SiteService", + "rpcName": "BatchCreateSites", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _BatchDeactivateSites( + _BaseSiteServiceRestTransport._BaseBatchDeactivateSites, SiteServiceRestStub + ): + def __hash__(self): + return hash("SiteServiceRestTransport.BatchDeactivateSites") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: site_service.BatchDeactivateSitesRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> site_service.BatchDeactivateSitesResponse: + r"""Call the batch deactivate sites method over HTTP. + + Args: + request (~.site_service.BatchDeactivateSitesRequest): + The request object. Request message for ``BatchDeactivateSites`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.site_service.BatchDeactivateSitesResponse: + Response object for ``BatchDeactivateSites`` method. + """ + + http_options = ( + _BaseSiteServiceRestTransport._BaseBatchDeactivateSites._get_http_options() + ) + + request, metadata = self._interceptor.pre_batch_deactivate_sites( + request, metadata + ) + transcoded_request = _BaseSiteServiceRestTransport._BaseBatchDeactivateSites._get_transcoded_request( + http_options, request + ) + + body = _BaseSiteServiceRestTransport._BaseBatchDeactivateSites._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseSiteServiceRestTransport._BaseBatchDeactivateSites._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.SiteServiceClient.BatchDeactivateSites", + extra={ + "serviceName": "google.ads.admanager.v1.SiteService", + "rpcName": "BatchDeactivateSites", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = SiteServiceRestTransport._BatchDeactivateSites._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = site_service.BatchDeactivateSitesResponse() + pb_resp = site_service.BatchDeactivateSitesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_deactivate_sites(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_deactivate_sites_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + site_service.BatchDeactivateSitesResponse.to_json(response) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.SiteServiceClient.batch_deactivate_sites", + extra={ + "serviceName": "google.ads.admanager.v1.SiteService", + "rpcName": "BatchDeactivateSites", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _BatchSubmitSitesForApproval( + _BaseSiteServiceRestTransport._BaseBatchSubmitSitesForApproval, + SiteServiceRestStub, + ): + def __hash__(self): + return hash("SiteServiceRestTransport.BatchSubmitSitesForApproval") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: site_service.BatchSubmitSitesForApprovalRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> site_service.BatchSubmitSitesForApprovalResponse: + r"""Call the batch submit sites for + approval method over HTTP. + + Args: + request (~.site_service.BatchSubmitSitesForApprovalRequest): + The request object. Request message for ``BatchSubmitSitesForApproval`` + method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.site_service.BatchSubmitSitesForApprovalResponse: + Response object for ``BatchSubmitSitesForApproval`` + method. + + """ + + http_options = ( + _BaseSiteServiceRestTransport._BaseBatchSubmitSitesForApproval._get_http_options() + ) + + request, metadata = self._interceptor.pre_batch_submit_sites_for_approval( + request, metadata + ) + transcoded_request = _BaseSiteServiceRestTransport._BaseBatchSubmitSitesForApproval._get_transcoded_request( + http_options, request + ) + + body = _BaseSiteServiceRestTransport._BaseBatchSubmitSitesForApproval._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseSiteServiceRestTransport._BaseBatchSubmitSitesForApproval._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.SiteServiceClient.BatchSubmitSitesForApproval", + extra={ + "serviceName": "google.ads.admanager.v1.SiteService", + "rpcName": "BatchSubmitSitesForApproval", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + SiteServiceRestTransport._BatchSubmitSitesForApproval._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = site_service.BatchSubmitSitesForApprovalResponse() + pb_resp = site_service.BatchSubmitSitesForApprovalResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_submit_sites_for_approval(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_batch_submit_sites_for_approval_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + site_service.BatchSubmitSitesForApprovalResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.SiteServiceClient.batch_submit_sites_for_approval", + extra={ + "serviceName": "google.ads.admanager.v1.SiteService", + "rpcName": "BatchSubmitSitesForApproval", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _BatchUpdateSites( + _BaseSiteServiceRestTransport._BaseBatchUpdateSites, SiteServiceRestStub + ): + def __hash__(self): + return hash("SiteServiceRestTransport.BatchUpdateSites") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: site_service.BatchUpdateSitesRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> site_service.BatchUpdateSitesResponse: + r"""Call the batch update sites method over HTTP. + + Args: + request (~.site_service.BatchUpdateSitesRequest): + The request object. Request object for ``BatchUpdateSites`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.site_service.BatchUpdateSitesResponse: + Response object for ``BatchUpdateSites`` method. + """ + + http_options = ( + _BaseSiteServiceRestTransport._BaseBatchUpdateSites._get_http_options() + ) + + request, metadata = self._interceptor.pre_batch_update_sites( + request, metadata + ) + transcoded_request = _BaseSiteServiceRestTransport._BaseBatchUpdateSites._get_transcoded_request( + http_options, request + ) + + body = _BaseSiteServiceRestTransport._BaseBatchUpdateSites._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseSiteServiceRestTransport._BaseBatchUpdateSites._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.SiteServiceClient.BatchUpdateSites", + extra={ + "serviceName": "google.ads.admanager.v1.SiteService", + "rpcName": "BatchUpdateSites", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = SiteServiceRestTransport._BatchUpdateSites._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = site_service.BatchUpdateSitesResponse() + pb_resp = site_service.BatchUpdateSitesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_update_sites(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_update_sites_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = site_service.BatchUpdateSitesResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.SiteServiceClient.batch_update_sites", + extra={ + "serviceName": "google.ads.admanager.v1.SiteService", + "rpcName": "BatchUpdateSites", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _CreateSite( + _BaseSiteServiceRestTransport._BaseCreateSite, SiteServiceRestStub + ): + def __hash__(self): + return hash("SiteServiceRestTransport.CreateSite") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: site_service.CreateSiteRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> site_messages.Site: + r"""Call the create site method over HTTP. + + Args: + request (~.site_service.CreateSiteRequest): + The request object. Request object for ``CreateSite`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.site_messages.Site: + A Site represents a domain owned or + represented by a network. For a parent + network managing other networks as part + of Multiple Customer Management "Manage + Inventory" model, it could be the + child's domain. + + """ + + http_options = ( + _BaseSiteServiceRestTransport._BaseCreateSite._get_http_options() + ) + + request, metadata = self._interceptor.pre_create_site(request, metadata) + transcoded_request = ( + _BaseSiteServiceRestTransport._BaseCreateSite._get_transcoded_request( + http_options, request + ) + ) + + body = _BaseSiteServiceRestTransport._BaseCreateSite._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = ( + _BaseSiteServiceRestTransport._BaseCreateSite._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.SiteServiceClient.CreateSite", + extra={ + "serviceName": "google.ads.admanager.v1.SiteService", + "rpcName": "CreateSite", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = SiteServiceRestTransport._CreateSite._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = site_messages.Site() + pb_resp = site_messages.Site.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_site(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_site_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = site_messages.Site.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.SiteServiceClient.create_site", + extra={ + "serviceName": "google.ads.admanager.v1.SiteService", + "rpcName": "CreateSite", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _GetSite(_BaseSiteServiceRestTransport._BaseGetSite, SiteServiceRestStub): + def __hash__(self): + return hash("SiteServiceRestTransport.GetSite") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: site_service.GetSiteRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> site_messages.Site: + r"""Call the get site method over HTTP. + + Args: + request (~.site_service.GetSiteRequest): + The request object. Request object for ``GetSite`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.site_messages.Site: + A Site represents a domain owned or + represented by a network. For a parent + network managing other networks as part + of Multiple Customer Management "Manage + Inventory" model, it could be the + child's domain. + + """ + + http_options = ( + _BaseSiteServiceRestTransport._BaseGetSite._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_site(request, metadata) + transcoded_request = ( + _BaseSiteServiceRestTransport._BaseGetSite._get_transcoded_request( + http_options, request + ) + ) + + # Jsonify the query params + query_params = ( + _BaseSiteServiceRestTransport._BaseGetSite._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.SiteServiceClient.GetSite", + extra={ + "serviceName": "google.ads.admanager.v1.SiteService", + "rpcName": "GetSite", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = SiteServiceRestTransport._GetSite._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = site_messages.Site() + pb_resp = site_messages.Site.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_site(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_site_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = site_messages.Site.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.SiteServiceClient.get_site", + extra={ + "serviceName": "google.ads.admanager.v1.SiteService", + "rpcName": "GetSite", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListSites(_BaseSiteServiceRestTransport._BaseListSites, SiteServiceRestStub): + def __hash__(self): + return hash("SiteServiceRestTransport.ListSites") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: site_service.ListSitesRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> site_service.ListSitesResponse: + r"""Call the list sites method over HTTP. + + Args: + request (~.site_service.ListSitesRequest): + The request object. Request object for ``ListSites`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.site_service.ListSitesResponse: + Response object for ``ListSitesRequest`` containing + matching ``Site`` objects. + + """ + + http_options = ( + _BaseSiteServiceRestTransport._BaseListSites._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_sites(request, metadata) + transcoded_request = ( + _BaseSiteServiceRestTransport._BaseListSites._get_transcoded_request( + http_options, request + ) + ) + + # Jsonify the query params + query_params = ( + _BaseSiteServiceRestTransport._BaseListSites._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.SiteServiceClient.ListSites", + extra={ + "serviceName": "google.ads.admanager.v1.SiteService", + "rpcName": "ListSites", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = SiteServiceRestTransport._ListSites._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = site_service.ListSitesResponse() + pb_resp = site_service.ListSitesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_sites(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_sites_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = site_service.ListSitesResponse.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.SiteServiceClient.list_sites", + extra={ + "serviceName": "google.ads.admanager.v1.SiteService", + "rpcName": "ListSites", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _UpdateSite( + _BaseSiteServiceRestTransport._BaseUpdateSite, SiteServiceRestStub + ): + def __hash__(self): + return hash("SiteServiceRestTransport.UpdateSite") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: site_service.UpdateSiteRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> site_messages.Site: + r"""Call the update site method over HTTP. + + Args: + request (~.site_service.UpdateSiteRequest): + The request object. Request object for ``UpdateSite`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.site_messages.Site: + A Site represents a domain owned or + represented by a network. For a parent + network managing other networks as part + of Multiple Customer Management "Manage + Inventory" model, it could be the + child's domain. + + """ + + http_options = ( + _BaseSiteServiceRestTransport._BaseUpdateSite._get_http_options() + ) + + request, metadata = self._interceptor.pre_update_site(request, metadata) + transcoded_request = ( + _BaseSiteServiceRestTransport._BaseUpdateSite._get_transcoded_request( + http_options, request + ) + ) + + body = _BaseSiteServiceRestTransport._BaseUpdateSite._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = ( + _BaseSiteServiceRestTransport._BaseUpdateSite._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.SiteServiceClient.UpdateSite", + extra={ + "serviceName": "google.ads.admanager.v1.SiteService", + "rpcName": "UpdateSite", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = SiteServiceRestTransport._UpdateSite._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = site_messages.Site() + pb_resp = site_messages.Site.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_update_site(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_site_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = site_messages.Site.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.SiteServiceClient.update_site", + extra={ + "serviceName": "google.ads.admanager.v1.SiteService", + "rpcName": "UpdateSite", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def batch_create_sites( + self, + ) -> Callable[ + [site_service.BatchCreateSitesRequest], site_service.BatchCreateSitesResponse + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchCreateSites(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_deactivate_sites( + self, + ) -> Callable[ + [site_service.BatchDeactivateSitesRequest], + site_service.BatchDeactivateSitesResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchDeactivateSites(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_submit_sites_for_approval( + self, + ) -> Callable[ + [site_service.BatchSubmitSitesForApprovalRequest], + site_service.BatchSubmitSitesForApprovalResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchSubmitSitesForApproval(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_update_sites( + self, + ) -> Callable[ + [site_service.BatchUpdateSitesRequest], site_service.BatchUpdateSitesResponse + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchUpdateSites(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_site( + self, + ) -> Callable[[site_service.CreateSiteRequest], site_messages.Site]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateSite(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_site(self) -> Callable[[site_service.GetSiteRequest], site_messages.Site]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetSite(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_sites( + self, + ) -> Callable[[site_service.ListSitesRequest], site_service.ListSitesResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListSites(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_site( + self, + ) -> Callable[[site_service.UpdateSiteRequest], site_messages.Site]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateSite(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseSiteServiceRestTransport._BaseGetOperation, SiteServiceRestStub + ): + def __hash__(self): + return hash("SiteServiceRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = ( + _BaseSiteServiceRestTransport._BaseGetOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = ( + _BaseSiteServiceRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + ) + + # Jsonify the query params + query_params = ( + _BaseSiteServiceRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.SiteServiceClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.SiteService", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = SiteServiceRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.SiteServiceAsyncClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.SiteService", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("SiteServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/transports/rest_base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/transports/rest_base.py new file mode 100644 index 000000000000..1de7a9f72e7e --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/site_service/transports/rest_base.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 json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.ads.admanager_v1.types import site_messages, site_service + +from .base import DEFAULT_CLIENT_INFO, SiteServiceTransport + + +class _BaseSiteServiceRestTransport(SiteServiceTransport): + """Base REST backend transport for SiteService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseBatchCreateSites: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/sites:batchCreate", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = site_service.BatchCreateSitesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseSiteServiceRestTransport._BaseBatchCreateSites._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseBatchDeactivateSites: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/sites:batchDeactivate", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = site_service.BatchDeactivateSitesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseSiteServiceRestTransport._BaseBatchDeactivateSites._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseBatchSubmitSitesForApproval: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/sites:batchSubmitForApproval", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = site_service.BatchSubmitSitesForApprovalRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseSiteServiceRestTransport._BaseBatchSubmitSitesForApproval._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseBatchUpdateSites: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/sites:batchUpdate", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = site_service.BatchUpdateSitesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseSiteServiceRestTransport._BaseBatchUpdateSites._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseCreateSite: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/sites", + "body": "site", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = site_service.CreateSiteRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseSiteServiceRestTransport._BaseCreateSite._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetSite: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/sites/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = site_service.GetSiteRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseSiteServiceRestTransport._BaseGetSite._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListSites: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=networks/*}/sites", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = site_service.ListSitesRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseSiteServiceRestTransport._BaseListSites._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateSite: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "updateMask": {}, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v1/{site.name=networks/*/sites/*}", + "body": "site", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = site_service.UpdateSiteRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseSiteServiceRestTransport._BaseUpdateSite._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/operations/reports/runs/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseSiteServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/__init__.py new file mode 100644 index 000000000000..277330973e74 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 TeamServiceClient + +__all__ = ("TeamServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/client.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/client.py new file mode 100644 index 000000000000..1e449ac30a77 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/client.py @@ -0,0 +1,1727 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +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.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version + +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.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore + +from google.ads.admanager_v1.services.team_service import pagers +from google.ads.admanager_v1.types import team_enums, team_messages, team_service + +from .transports.base import DEFAULT_CLIENT_INFO, TeamServiceTransport +from .transports.rest import TeamServiceRestTransport + + +class TeamServiceClientMeta(type): + """Metaclass for the TeamService 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[TeamServiceTransport]] + _transport_registry["rest"] = TeamServiceRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[TeamServiceTransport]: + """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 TeamServiceClient(metaclass=TeamServiceClientMeta): + """Provides methods for handling ``Team`` objects.""" + + @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 = "admanager.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "admanager.{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: + TeamServiceClient: 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: + TeamServiceClient: 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) -> TeamServiceTransport: + """Returns the transport used by the client instance. + + Returns: + TeamServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def network_path( + network_code: str, + ) -> str: + """Returns a fully-qualified network string.""" + return "networks/{network_code}".format( + network_code=network_code, + ) + + @staticmethod + def parse_network_path(path: str) -> Dict[str, str]: + """Parses a network path into its component segments.""" + m = re.match(r"^networks/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def team_path( + network_code: str, + team: str, + ) -> str: + """Returns a fully-qualified team string.""" + return "networks/{network_code}/teams/{team}".format( + network_code=network_code, + team=team, + ) + + @staticmethod + def parse_team_path(path: str) -> Dict[str, str]: + """Parses a team path into its component segments.""" + m = re.match(r"^networks/(?P.+?)/teams/(?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 = TeamServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = TeamServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = TeamServiceClient._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 = TeamServiceClient._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, TeamServiceTransport, Callable[..., TeamServiceTransport]] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the team 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,TeamServiceTransport,Callable[..., TeamServiceTransport]]]): + 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 TeamServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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, + ) = TeamServiceClient._read_environment_variables() + self._client_cert_source = TeamServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = TeamServiceClient._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, TeamServiceTransport) + if transport_provided: + # transport is a TeamServiceTransport 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(TeamServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = self._api_endpoint or TeamServiceClient._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[TeamServiceTransport], Callable[..., TeamServiceTransport] + ] = ( + TeamServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., TeamServiceTransport], 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.admanager_v1.TeamServiceClient`.", + extra={ + "serviceName": "google.ads.admanager.v1.TeamService", + "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.admanager.v1.TeamService", + "credentialsType": None, + }, + ) + + def get_team( + self, + request: Optional[Union[team_service.GetTeamRequest, dict]] = None, + *, + 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]]] = (), + ) -> team_messages.Team: + r"""API to retrieve a ``Team`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_get_team(): + # Create a client + client = admanager_v1.TeamServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetTeamRequest( + name="name_value", + ) + + # Make the request + response = client.get_team(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.GetTeamRequest, dict]): + The request object. Request object for ``GetTeam`` method. + name (str): + Required. The resource name of the Team. Format: + ``networks/{network_code}/teams/{team_id}`` + + This corresponds to the ``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.admanager_v1.types.Team: + A Team defines a grouping of users + and what entities they have access to. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, team_service.GetTeamRequest): + request = team_service.GetTeamRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_team] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_teams( + self, + request: Optional[Union[team_service.ListTeamsRequest, dict]] = None, + *, + parent: 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.ListTeamsPager: + r"""API to retrieve a list of ``Team`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_list_teams(): + # Create a client + client = admanager_v1.TeamServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListTeamsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_teams(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.ListTeamsRequest, dict]): + The request object. Request object for ``ListTeams`` method. + parent (str): + Required. The parent, which owns this collection of + Teams. Format: ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.services.team_service.pagers.ListTeamsPager: + Response object for ListTeamsRequest containing matching + Team objects. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, team_service.ListTeamsRequest): + request = team_service.ListTeamsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_teams] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.ListTeamsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def create_team( + self, + request: Optional[Union[team_service.CreateTeamRequest, dict]] = None, + *, + parent: Optional[str] = None, + team: Optional[team_messages.Team] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> team_messages.Team: + r"""API to create a ``Team`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_create_team(): + # Create a client + client = admanager_v1.TeamServiceClient() + + # Initialize request argument(s) + request = admanager_v1.CreateTeamRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_team(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.CreateTeamRequest, dict]): + The request object. Request object for ``CreateTeam`` method. + parent (str): + Required. The parent resource where this ``Team`` will + be created. Format: ``networks/{network_code}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + team (google.ads.admanager_v1.types.Team): + Required. The ``Team`` to create. + This corresponds to the ``team`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.Team: + A Team defines a grouping of users + and what entities they have access to. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, team] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, team_service.CreateTeamRequest): + request = team_service.CreateTeamRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if team is not None: + request.team = team + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_team] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def batch_create_teams( + self, + request: Optional[Union[team_service.BatchCreateTeamsRequest, dict]] = None, + *, + parent: Optional[str] = None, + requests: Optional[MutableSequence[team_service.CreateTeamRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> team_service.BatchCreateTeamsResponse: + r"""API to batch create ``Team`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_batch_create_teams(): + # Create a client + client = admanager_v1.TeamServiceClient() + + # Initialize request argument(s) + requests = admanager_v1.CreateTeamRequest() + requests.parent = "parent_value" + + request = admanager_v1.BatchCreateTeamsRequest( + parent="parent_value", + requests=requests, + ) + + # Make the request + response = client.batch_create_teams(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.BatchCreateTeamsRequest, dict]): + The request object. Request object for ``BatchCreateTeams`` method. + parent (str): + Required. The parent resource where ``Teams`` will be + created. Format: ``networks/{network_code}`` The parent + field in the CreateTeamRequest must match this field. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + requests (MutableSequence[google.ads.admanager_v1.types.CreateTeamRequest]): + Required. The ``Team`` objects to create. A maximum of + 100 objects can be created in a batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.BatchCreateTeamsResponse: + Response object for BatchCreateTeams method. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, requests] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, team_service.BatchCreateTeamsRequest): + request = team_service.BatchCreateTeamsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_create_teams] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe 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_team( + self, + request: Optional[Union[team_service.UpdateTeamRequest, dict]] = None, + *, + team: Optional[team_messages.Team] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> team_messages.Team: + r"""API to update a ``Team`` object. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_update_team(): + # Create a client + client = admanager_v1.TeamServiceClient() + + # Initialize request argument(s) + request = admanager_v1.UpdateTeamRequest( + ) + + # Make the request + response = client.update_team(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.UpdateTeamRequest, dict]): + The request object. Request object for ``UpdateTeam`` method. + team (google.ads.admanager_v1.types.Team): + Required. The ``Team`` to update. + + The ``Team``'s ``name`` is used to identify the ``Team`` + to update. + + This corresponds to the ``team`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Required. The list of fields to + update. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.Team: + A Team defines a grouping of users + and what entities they have access to. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [team, update_mask] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, team_service.UpdateTeamRequest): + request = team_service.UpdateTeamRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if team is not None: + request.team = team + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_team] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("team.name", request.team.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 batch_update_teams( + self, + request: Optional[Union[team_service.BatchUpdateTeamsRequest, dict]] = None, + *, + parent: Optional[str] = None, + requests: Optional[MutableSequence[team_service.UpdateTeamRequest]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> team_service.BatchUpdateTeamsResponse: + r"""API to batch update ``Team`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_batch_update_teams(): + # Create a client + client = admanager_v1.TeamServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchUpdateTeamsRequest( + parent="parent_value", + ) + + # Make the request + response = client.batch_update_teams(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.BatchUpdateTeamsRequest, dict]): + The request object. Request object for ``BatchUpdateTeams`` method. + parent (str): + Required. The parent resource where ``Teams`` will be + updated. Format: ``networks/{network_code}`` The parent + field in the UpdateTeamRequest must match this field. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + requests (MutableSequence[google.ads.admanager_v1.types.UpdateTeamRequest]): + Required. The ``Team`` objects to update. A maximum of + 100 objects can be updated in a batch. + + This corresponds to the ``requests`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.BatchUpdateTeamsResponse: + Response object for BatchUpdateTeams method. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, requests] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, team_service.BatchUpdateTeamsRequest): + request = team_service.BatchUpdateTeamsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if requests is not None: + request.requests = requests + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_update_teams] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def batch_activate_teams( + self, + request: Optional[Union[team_service.BatchActivateTeamsRequest, dict]] = None, + *, + parent: Optional[str] = None, + names: 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]]] = (), + ) -> team_service.BatchActivateTeamsResponse: + r"""API to batch activate ``Team`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_batch_activate_teams(): + # Create a client + client = admanager_v1.TeamServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchActivateTeamsRequest( + parent="parent_value", + names=['names_value1', 'names_value2'], + ) + + # Make the request + response = client.batch_activate_teams(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.BatchActivateTeamsRequest, dict]): + The request object. Request message for ``BatchActivateTeams`` method. + parent (str): + Required. Format: ``networks/{network_code}`` + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + names (MutableSequence[str]): + Required. The resource names of the ``Team``\ s to + activate. Format: + ``networks/{network_code}/teams/{team_id}`` + + This corresponds to the ``names`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.BatchActivateTeamsResponse: + Response object for BatchActivateTeams method. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, names] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, team_service.BatchActivateTeamsRequest): + request = team_service.BatchActivateTeamsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if names is not None: + request.names = names + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_activate_teams] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def batch_deactivate_teams( + self, + request: Optional[Union[team_service.BatchDeactivateTeamsRequest, dict]] = None, + *, + parent: Optional[str] = None, + names: 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]]] = (), + ) -> team_service.BatchDeactivateTeamsResponse: + r"""API to batch deactivate ``Team`` objects. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.ads import admanager_v1 + + def sample_batch_deactivate_teams(): + # Create a client + client = admanager_v1.TeamServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchDeactivateTeamsRequest( + parent="parent_value", + names=['names_value1', 'names_value2'], + ) + + # Make the request + response = client.batch_deactivate_teams(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.ads.admanager_v1.types.BatchDeactivateTeamsRequest, dict]): + The request object. Request message for ``BatchDeactivateTeams`` method. + parent (str): + Required. Format: ``networks/{network_code}`` + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + names (MutableSequence[str]): + Required. The resource names of the ``Team``\ s to + deactivate. Format: + ``networks/{network_code}/teams/{team_id}`` + + This corresponds to the ``names`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.ads.admanager_v1.types.BatchDeactivateTeamsResponse: + Response object for BatchDeactivateTeams method. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, names] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, team_service.BatchDeactivateTeamsRequest): + request = team_service.BatchDeactivateTeamsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if names is not None: + request.names = names + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_deactivate_teams] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe 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) -> "TeamServiceClient": + 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() + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("TeamServiceClient",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/pagers.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/pagers.py new file mode 100644 index 000000000000..406ed033d41e --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/pagers.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +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 + +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.admanager_v1.types import team_messages, team_service + + +class ListTeamsPager: + """A pager for iterating through ``list_teams`` requests. + + This class thinly wraps an initial + :class:`google.ads.admanager_v1.types.ListTeamsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``teams`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListTeams`` requests and continue to iterate + through the ``teams`` field on the + corresponding responses. + + All the usual :class:`google.ads.admanager_v1.types.ListTeamsResponse` + 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[..., team_service.ListTeamsResponse], + request: team_service.ListTeamsRequest, + response: team_service.ListTeamsResponse, + *, + 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.admanager_v1.types.ListTeamsRequest): + The initial request object. + response (google.ads.admanager_v1.types.ListTeamsResponse): + 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 = team_service.ListTeamsRequest(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[team_service.ListTeamsResponse]: + 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[team_messages.Team]: + for page in self.pages: + yield from page.teams + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/transports/README.rst b/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/transports/README.rst new file mode 100644 index 000000000000..5feeecaf4ccb --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`TeamServiceTransport` is the ABC for all transports. +- public child `TeamServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `TeamServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseTeamServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `TeamServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/transports/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/transports/__init__.py new file mode 100644 index 000000000000..6f2617a16f76 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/transports/__init__.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 typing import Dict, Type + +from .base import TeamServiceTransport +from .rest import TeamServiceRestInterceptor, TeamServiceRestTransport + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[TeamServiceTransport]] +_transport_registry["rest"] = TeamServiceRestTransport + +__all__ = ( + "TeamServiceTransport", + "TeamServiceRestTransport", + "TeamServiceRestInterceptor", +) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/transports/base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/transports/base.py new file mode 100644 index 000000000000..9604dfc7cb7d --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/transports/base.py @@ -0,0 +1,293 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.admanager_v1 import gapic_version as package_version +from google.ads.admanager_v1.types import team_messages, team_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 TeamServiceTransport(abc.ABC): + """Abstract transport class for TeamService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/admanager",) + + DEFAULT_HOST: str = "admanager.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: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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_team: gapic_v1.method.wrap_method( + self.get_team, + default_timeout=None, + client_info=client_info, + ), + self.list_teams: gapic_v1.method.wrap_method( + self.list_teams, + default_timeout=None, + client_info=client_info, + ), + self.create_team: gapic_v1.method.wrap_method( + self.create_team, + default_timeout=None, + client_info=client_info, + ), + self.batch_create_teams: gapic_v1.method.wrap_method( + self.batch_create_teams, + default_timeout=None, + client_info=client_info, + ), + self.update_team: gapic_v1.method.wrap_method( + self.update_team, + default_timeout=None, + client_info=client_info, + ), + self.batch_update_teams: gapic_v1.method.wrap_method( + self.batch_update_teams, + default_timeout=None, + client_info=client_info, + ), + self.batch_activate_teams: gapic_v1.method.wrap_method( + self.batch_activate_teams, + default_timeout=None, + client_info=client_info, + ), + self.batch_deactivate_teams: gapic_v1.method.wrap_method( + self.batch_deactivate_teams, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + 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_team( + self, + ) -> Callable[ + [team_service.GetTeamRequest], + Union[team_messages.Team, Awaitable[team_messages.Team]], + ]: + raise NotImplementedError() + + @property + def list_teams( + self, + ) -> Callable[ + [team_service.ListTeamsRequest], + Union[ + team_service.ListTeamsResponse, Awaitable[team_service.ListTeamsResponse] + ], + ]: + raise NotImplementedError() + + @property + def create_team( + self, + ) -> Callable[ + [team_service.CreateTeamRequest], + Union[team_messages.Team, Awaitable[team_messages.Team]], + ]: + raise NotImplementedError() + + @property + def batch_create_teams( + self, + ) -> Callable[ + [team_service.BatchCreateTeamsRequest], + Union[ + team_service.BatchCreateTeamsResponse, + Awaitable[team_service.BatchCreateTeamsResponse], + ], + ]: + raise NotImplementedError() + + @property + def update_team( + self, + ) -> Callable[ + [team_service.UpdateTeamRequest], + Union[team_messages.Team, Awaitable[team_messages.Team]], + ]: + raise NotImplementedError() + + @property + def batch_update_teams( + self, + ) -> Callable[ + [team_service.BatchUpdateTeamsRequest], + Union[ + team_service.BatchUpdateTeamsResponse, + Awaitable[team_service.BatchUpdateTeamsResponse], + ], + ]: + raise NotImplementedError() + + @property + def batch_activate_teams( + self, + ) -> Callable[ + [team_service.BatchActivateTeamsRequest], + Union[ + team_service.BatchActivateTeamsResponse, + Awaitable[team_service.BatchActivateTeamsResponse], + ], + ]: + raise NotImplementedError() + + @property + def batch_deactivate_teams( + self, + ) -> Callable[ + [team_service.BatchDeactivateTeamsRequest], + Union[ + team_service.BatchDeactivateTeamsResponse, + Awaitable[team_service.BatchDeactivateTeamsResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("TeamServiceTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/transports/rest.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/transports/rest.py new file mode 100644 index 000000000000..8b23bd9d774c --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/transports/rest.py @@ -0,0 +1,2087 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.ads.admanager_v1.types import team_messages, team_service + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseTeamServiceRestTransport + +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 = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class TeamServiceRestInterceptor: + """Interceptor for TeamService. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the TeamServiceRestTransport. + + .. code-block:: python + class MyCustomTeamServiceInterceptor(TeamServiceRestInterceptor): + def pre_batch_activate_teams(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_activate_teams(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_create_teams(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_create_teams(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_deactivate_teams(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_deactivate_teams(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_update_teams(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_update_teams(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_team(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_team(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_team(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_team(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_teams(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_teams(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_team(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_team(self, response): + logging.log(f"Received response: {response}") + return response + + transport = TeamServiceRestTransport(interceptor=MyCustomTeamServiceInterceptor()) + client = TeamServiceClient(transport=transport) + + + """ + + def pre_batch_activate_teams( + self, + request: team_service.BatchActivateTeamsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + team_service.BatchActivateTeamsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for batch_activate_teams + + Override in a subclass to manipulate the request or metadata + before they are sent to the TeamService server. + """ + return request, metadata + + def post_batch_activate_teams( + self, response: team_service.BatchActivateTeamsResponse + ) -> team_service.BatchActivateTeamsResponse: + """Post-rpc interceptor for batch_activate_teams + + DEPRECATED. Please use the `post_batch_activate_teams_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the TeamService server but before + it is returned to user code. This `post_batch_activate_teams` interceptor runs + before the `post_batch_activate_teams_with_metadata` interceptor. + """ + return response + + def post_batch_activate_teams_with_metadata( + self, + response: team_service.BatchActivateTeamsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + team_service.BatchActivateTeamsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for batch_activate_teams + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TeamService server but before it is returned to user code. + + We recommend only using this `post_batch_activate_teams_with_metadata` + interceptor in new development instead of the `post_batch_activate_teams` interceptor. + When both interceptors are used, this `post_batch_activate_teams_with_metadata` interceptor runs after the + `post_batch_activate_teams` interceptor. The (possibly modified) response returned by + `post_batch_activate_teams` will be passed to + `post_batch_activate_teams_with_metadata`. + """ + return response, metadata + + def pre_batch_create_teams( + self, + request: team_service.BatchCreateTeamsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + team_service.BatchCreateTeamsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for batch_create_teams + + Override in a subclass to manipulate the request or metadata + before they are sent to the TeamService server. + """ + return request, metadata + + def post_batch_create_teams( + self, response: team_service.BatchCreateTeamsResponse + ) -> team_service.BatchCreateTeamsResponse: + """Post-rpc interceptor for batch_create_teams + + DEPRECATED. Please use the `post_batch_create_teams_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the TeamService server but before + it is returned to user code. This `post_batch_create_teams` interceptor runs + before the `post_batch_create_teams_with_metadata` interceptor. + """ + return response + + def post_batch_create_teams_with_metadata( + self, + response: team_service.BatchCreateTeamsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + team_service.BatchCreateTeamsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for batch_create_teams + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TeamService server but before it is returned to user code. + + We recommend only using this `post_batch_create_teams_with_metadata` + interceptor in new development instead of the `post_batch_create_teams` interceptor. + When both interceptors are used, this `post_batch_create_teams_with_metadata` interceptor runs after the + `post_batch_create_teams` interceptor. The (possibly modified) response returned by + `post_batch_create_teams` will be passed to + `post_batch_create_teams_with_metadata`. + """ + return response, metadata + + def pre_batch_deactivate_teams( + self, + request: team_service.BatchDeactivateTeamsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + team_service.BatchDeactivateTeamsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for batch_deactivate_teams + + Override in a subclass to manipulate the request or metadata + before they are sent to the TeamService server. + """ + return request, metadata + + def post_batch_deactivate_teams( + self, response: team_service.BatchDeactivateTeamsResponse + ) -> team_service.BatchDeactivateTeamsResponse: + """Post-rpc interceptor for batch_deactivate_teams + + DEPRECATED. Please use the `post_batch_deactivate_teams_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the TeamService server but before + it is returned to user code. This `post_batch_deactivate_teams` interceptor runs + before the `post_batch_deactivate_teams_with_metadata` interceptor. + """ + return response + + def post_batch_deactivate_teams_with_metadata( + self, + response: team_service.BatchDeactivateTeamsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + team_service.BatchDeactivateTeamsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for batch_deactivate_teams + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TeamService server but before it is returned to user code. + + We recommend only using this `post_batch_deactivate_teams_with_metadata` + interceptor in new development instead of the `post_batch_deactivate_teams` interceptor. + When both interceptors are used, this `post_batch_deactivate_teams_with_metadata` interceptor runs after the + `post_batch_deactivate_teams` interceptor. The (possibly modified) response returned by + `post_batch_deactivate_teams` will be passed to + `post_batch_deactivate_teams_with_metadata`. + """ + return response, metadata + + def pre_batch_update_teams( + self, + request: team_service.BatchUpdateTeamsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + team_service.BatchUpdateTeamsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for batch_update_teams + + Override in a subclass to manipulate the request or metadata + before they are sent to the TeamService server. + """ + return request, metadata + + def post_batch_update_teams( + self, response: team_service.BatchUpdateTeamsResponse + ) -> team_service.BatchUpdateTeamsResponse: + """Post-rpc interceptor for batch_update_teams + + DEPRECATED. Please use the `post_batch_update_teams_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the TeamService server but before + it is returned to user code. This `post_batch_update_teams` interceptor runs + before the `post_batch_update_teams_with_metadata` interceptor. + """ + return response + + def post_batch_update_teams_with_metadata( + self, + response: team_service.BatchUpdateTeamsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + team_service.BatchUpdateTeamsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for batch_update_teams + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TeamService server but before it is returned to user code. + + We recommend only using this `post_batch_update_teams_with_metadata` + interceptor in new development instead of the `post_batch_update_teams` interceptor. + When both interceptors are used, this `post_batch_update_teams_with_metadata` interceptor runs after the + `post_batch_update_teams` interceptor. The (possibly modified) response returned by + `post_batch_update_teams` will be passed to + `post_batch_update_teams_with_metadata`. + """ + return response, metadata + + def pre_create_team( + self, + request: team_service.CreateTeamRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[team_service.CreateTeamRequest, Sequence[Tuple[str, Union[str, bytes]]]]: + """Pre-rpc interceptor for create_team + + Override in a subclass to manipulate the request or metadata + before they are sent to the TeamService server. + """ + return request, metadata + + def post_create_team(self, response: team_messages.Team) -> team_messages.Team: + """Post-rpc interceptor for create_team + + DEPRECATED. Please use the `post_create_team_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the TeamService server but before + it is returned to user code. This `post_create_team` interceptor runs + before the `post_create_team_with_metadata` interceptor. + """ + return response + + def post_create_team_with_metadata( + self, + response: team_messages.Team, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[team_messages.Team, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_team + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TeamService server but before it is returned to user code. + + We recommend only using this `post_create_team_with_metadata` + interceptor in new development instead of the `post_create_team` interceptor. + When both interceptors are used, this `post_create_team_with_metadata` interceptor runs after the + `post_create_team` interceptor. The (possibly modified) response returned by + `post_create_team` will be passed to + `post_create_team_with_metadata`. + """ + return response, metadata + + def pre_get_team( + self, + request: team_service.GetTeamRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[team_service.GetTeamRequest, Sequence[Tuple[str, Union[str, bytes]]]]: + """Pre-rpc interceptor for get_team + + Override in a subclass to manipulate the request or metadata + before they are sent to the TeamService server. + """ + return request, metadata + + def post_get_team(self, response: team_messages.Team) -> team_messages.Team: + """Post-rpc interceptor for get_team + + DEPRECATED. Please use the `post_get_team_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the TeamService server but before + it is returned to user code. This `post_get_team` interceptor runs + before the `post_get_team_with_metadata` interceptor. + """ + return response + + def post_get_team_with_metadata( + self, + response: team_messages.Team, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[team_messages.Team, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_team + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TeamService server but before it is returned to user code. + + We recommend only using this `post_get_team_with_metadata` + interceptor in new development instead of the `post_get_team` interceptor. + When both interceptors are used, this `post_get_team_with_metadata` interceptor runs after the + `post_get_team` interceptor. The (possibly modified) response returned by + `post_get_team` will be passed to + `post_get_team_with_metadata`. + """ + return response, metadata + + def pre_list_teams( + self, + request: team_service.ListTeamsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[team_service.ListTeamsRequest, Sequence[Tuple[str, Union[str, bytes]]]]: + """Pre-rpc interceptor for list_teams + + Override in a subclass to manipulate the request or metadata + before they are sent to the TeamService server. + """ + return request, metadata + + def post_list_teams( + self, response: team_service.ListTeamsResponse + ) -> team_service.ListTeamsResponse: + """Post-rpc interceptor for list_teams + + DEPRECATED. Please use the `post_list_teams_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the TeamService server but before + it is returned to user code. This `post_list_teams` interceptor runs + before the `post_list_teams_with_metadata` interceptor. + """ + return response + + def post_list_teams_with_metadata( + self, + response: team_service.ListTeamsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[team_service.ListTeamsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_teams + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TeamService server but before it is returned to user code. + + We recommend only using this `post_list_teams_with_metadata` + interceptor in new development instead of the `post_list_teams` interceptor. + When both interceptors are used, this `post_list_teams_with_metadata` interceptor runs after the + `post_list_teams` interceptor. The (possibly modified) response returned by + `post_list_teams` will be passed to + `post_list_teams_with_metadata`. + """ + return response, metadata + + def pre_update_team( + self, + request: team_service.UpdateTeamRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[team_service.UpdateTeamRequest, Sequence[Tuple[str, Union[str, bytes]]]]: + """Pre-rpc interceptor for update_team + + Override in a subclass to manipulate the request or metadata + before they are sent to the TeamService server. + """ + return request, metadata + + def post_update_team(self, response: team_messages.Team) -> team_messages.Team: + """Post-rpc interceptor for update_team + + DEPRECATED. Please use the `post_update_team_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the TeamService server but before + it is returned to user code. This `post_update_team` interceptor runs + before the `post_update_team_with_metadata` interceptor. + """ + return response + + def post_update_team_with_metadata( + self, + response: team_messages.Team, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[team_messages.Team, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_team + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TeamService server but before it is returned to user code. + + We recommend only using this `post_update_team_with_metadata` + interceptor in new development instead of the `post_update_team` interceptor. + When both interceptors are used, this `post_update_team_with_metadata` interceptor runs after the + `post_update_team` interceptor. The (possibly modified) response returned by + `post_update_team` will be passed to + `post_update_team_with_metadata`. + """ + return response, metadata + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the TeamService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the TeamService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class TeamServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: TeamServiceRestInterceptor + + +class TeamServiceRestTransport(_BaseTeamServiceRestTransport): + """REST backend synchronous transport for TeamService. + + Provides methods for handling ``Team`` objects. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[TeamServiceRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or TeamServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _BatchActivateTeams( + _BaseTeamServiceRestTransport._BaseBatchActivateTeams, TeamServiceRestStub + ): + def __hash__(self): + return hash("TeamServiceRestTransport.BatchActivateTeams") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: team_service.BatchActivateTeamsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> team_service.BatchActivateTeamsResponse: + r"""Call the batch activate teams method over HTTP. + + Args: + request (~.team_service.BatchActivateTeamsRequest): + The request object. Request message for ``BatchActivateTeams`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.team_service.BatchActivateTeamsResponse: + Response object for ``BatchActivateTeams`` method. + """ + + http_options = ( + _BaseTeamServiceRestTransport._BaseBatchActivateTeams._get_http_options() + ) + + request, metadata = self._interceptor.pre_batch_activate_teams( + request, metadata + ) + transcoded_request = _BaseTeamServiceRestTransport._BaseBatchActivateTeams._get_transcoded_request( + http_options, request + ) + + body = _BaseTeamServiceRestTransport._BaseBatchActivateTeams._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseTeamServiceRestTransport._BaseBatchActivateTeams._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.TeamServiceClient.BatchActivateTeams", + extra={ + "serviceName": "google.ads.admanager.v1.TeamService", + "rpcName": "BatchActivateTeams", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = TeamServiceRestTransport._BatchActivateTeams._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = team_service.BatchActivateTeamsResponse() + pb_resp = team_service.BatchActivateTeamsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_activate_teams(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_activate_teams_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = team_service.BatchActivateTeamsResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.TeamServiceClient.batch_activate_teams", + extra={ + "serviceName": "google.ads.admanager.v1.TeamService", + "rpcName": "BatchActivateTeams", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _BatchCreateTeams( + _BaseTeamServiceRestTransport._BaseBatchCreateTeams, TeamServiceRestStub + ): + def __hash__(self): + return hash("TeamServiceRestTransport.BatchCreateTeams") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: team_service.BatchCreateTeamsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> team_service.BatchCreateTeamsResponse: + r"""Call the batch create teams method over HTTP. + + Args: + request (~.team_service.BatchCreateTeamsRequest): + The request object. Request object for ``BatchCreateTeams`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.team_service.BatchCreateTeamsResponse: + Response object for ``BatchCreateTeams`` method. + """ + + http_options = ( + _BaseTeamServiceRestTransport._BaseBatchCreateTeams._get_http_options() + ) + + request, metadata = self._interceptor.pre_batch_create_teams( + request, metadata + ) + transcoded_request = _BaseTeamServiceRestTransport._BaseBatchCreateTeams._get_transcoded_request( + http_options, request + ) + + body = _BaseTeamServiceRestTransport._BaseBatchCreateTeams._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseTeamServiceRestTransport._BaseBatchCreateTeams._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.TeamServiceClient.BatchCreateTeams", + extra={ + "serviceName": "google.ads.admanager.v1.TeamService", + "rpcName": "BatchCreateTeams", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = TeamServiceRestTransport._BatchCreateTeams._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = team_service.BatchCreateTeamsResponse() + pb_resp = team_service.BatchCreateTeamsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_create_teams(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_create_teams_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = team_service.BatchCreateTeamsResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.TeamServiceClient.batch_create_teams", + extra={ + "serviceName": "google.ads.admanager.v1.TeamService", + "rpcName": "BatchCreateTeams", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _BatchDeactivateTeams( + _BaseTeamServiceRestTransport._BaseBatchDeactivateTeams, TeamServiceRestStub + ): + def __hash__(self): + return hash("TeamServiceRestTransport.BatchDeactivateTeams") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: team_service.BatchDeactivateTeamsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> team_service.BatchDeactivateTeamsResponse: + r"""Call the batch deactivate teams method over HTTP. + + Args: + request (~.team_service.BatchDeactivateTeamsRequest): + The request object. Request message for ``BatchDeactivateTeams`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.team_service.BatchDeactivateTeamsResponse: + Response object for ``BatchDeactivateTeams`` method. + """ + + http_options = ( + _BaseTeamServiceRestTransport._BaseBatchDeactivateTeams._get_http_options() + ) + + request, metadata = self._interceptor.pre_batch_deactivate_teams( + request, metadata + ) + transcoded_request = _BaseTeamServiceRestTransport._BaseBatchDeactivateTeams._get_transcoded_request( + http_options, request + ) + + body = _BaseTeamServiceRestTransport._BaseBatchDeactivateTeams._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseTeamServiceRestTransport._BaseBatchDeactivateTeams._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.TeamServiceClient.BatchDeactivateTeams", + extra={ + "serviceName": "google.ads.admanager.v1.TeamService", + "rpcName": "BatchDeactivateTeams", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = TeamServiceRestTransport._BatchDeactivateTeams._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = team_service.BatchDeactivateTeamsResponse() + pb_resp = team_service.BatchDeactivateTeamsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_deactivate_teams(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_deactivate_teams_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + team_service.BatchDeactivateTeamsResponse.to_json(response) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.TeamServiceClient.batch_deactivate_teams", + extra={ + "serviceName": "google.ads.admanager.v1.TeamService", + "rpcName": "BatchDeactivateTeams", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _BatchUpdateTeams( + _BaseTeamServiceRestTransport._BaseBatchUpdateTeams, TeamServiceRestStub + ): + def __hash__(self): + return hash("TeamServiceRestTransport.BatchUpdateTeams") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: team_service.BatchUpdateTeamsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> team_service.BatchUpdateTeamsResponse: + r"""Call the batch update teams method over HTTP. + + Args: + request (~.team_service.BatchUpdateTeamsRequest): + The request object. Request object for ``BatchUpdateTeams`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.team_service.BatchUpdateTeamsResponse: + Response object for ``BatchUpdateTeams`` method. + """ + + http_options = ( + _BaseTeamServiceRestTransport._BaseBatchUpdateTeams._get_http_options() + ) + + request, metadata = self._interceptor.pre_batch_update_teams( + request, metadata + ) + transcoded_request = _BaseTeamServiceRestTransport._BaseBatchUpdateTeams._get_transcoded_request( + http_options, request + ) + + body = _BaseTeamServiceRestTransport._BaseBatchUpdateTeams._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseTeamServiceRestTransport._BaseBatchUpdateTeams._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.TeamServiceClient.BatchUpdateTeams", + extra={ + "serviceName": "google.ads.admanager.v1.TeamService", + "rpcName": "BatchUpdateTeams", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = TeamServiceRestTransport._BatchUpdateTeams._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = team_service.BatchUpdateTeamsResponse() + pb_resp = team_service.BatchUpdateTeamsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_batch_update_teams(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_update_teams_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = team_service.BatchUpdateTeamsResponse.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.TeamServiceClient.batch_update_teams", + extra={ + "serviceName": "google.ads.admanager.v1.TeamService", + "rpcName": "BatchUpdateTeams", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _CreateTeam( + _BaseTeamServiceRestTransport._BaseCreateTeam, TeamServiceRestStub + ): + def __hash__(self): + return hash("TeamServiceRestTransport.CreateTeam") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: team_service.CreateTeamRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> team_messages.Team: + r"""Call the create team method over HTTP. + + Args: + request (~.team_service.CreateTeamRequest): + The request object. Request object for ``CreateTeam`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.team_messages.Team: + A Team defines a grouping of users + and what entities they have access to. + + """ + + http_options = ( + _BaseTeamServiceRestTransport._BaseCreateTeam._get_http_options() + ) + + request, metadata = self._interceptor.pre_create_team(request, metadata) + transcoded_request = ( + _BaseTeamServiceRestTransport._BaseCreateTeam._get_transcoded_request( + http_options, request + ) + ) + + body = _BaseTeamServiceRestTransport._BaseCreateTeam._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = ( + _BaseTeamServiceRestTransport._BaseCreateTeam._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.TeamServiceClient.CreateTeam", + extra={ + "serviceName": "google.ads.admanager.v1.TeamService", + "rpcName": "CreateTeam", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = TeamServiceRestTransport._CreateTeam._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = team_messages.Team() + pb_resp = team_messages.Team.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_team(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_team_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = team_messages.Team.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.TeamServiceClient.create_team", + extra={ + "serviceName": "google.ads.admanager.v1.TeamService", + "rpcName": "CreateTeam", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _GetTeam(_BaseTeamServiceRestTransport._BaseGetTeam, TeamServiceRestStub): + def __hash__(self): + return hash("TeamServiceRestTransport.GetTeam") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: team_service.GetTeamRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> team_messages.Team: + r"""Call the get team method over HTTP. + + Args: + request (~.team_service.GetTeamRequest): + The request object. Request object for ``GetTeam`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.team_messages.Team: + A Team defines a grouping of users + and what entities they have access to. + + """ + + http_options = ( + _BaseTeamServiceRestTransport._BaseGetTeam._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_team(request, metadata) + transcoded_request = ( + _BaseTeamServiceRestTransport._BaseGetTeam._get_transcoded_request( + http_options, request + ) + ) + + # Jsonify the query params + query_params = ( + _BaseTeamServiceRestTransport._BaseGetTeam._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.TeamServiceClient.GetTeam", + extra={ + "serviceName": "google.ads.admanager.v1.TeamService", + "rpcName": "GetTeam", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = TeamServiceRestTransport._GetTeam._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = team_messages.Team() + pb_resp = team_messages.Team.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_team(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_team_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = team_messages.Team.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.TeamServiceClient.get_team", + extra={ + "serviceName": "google.ads.admanager.v1.TeamService", + "rpcName": "GetTeam", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListTeams(_BaseTeamServiceRestTransport._BaseListTeams, TeamServiceRestStub): + def __hash__(self): + return hash("TeamServiceRestTransport.ListTeams") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: team_service.ListTeamsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> team_service.ListTeamsResponse: + r"""Call the list teams method over HTTP. + + Args: + request (~.team_service.ListTeamsRequest): + The request object. Request object for ``ListTeams`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.team_service.ListTeamsResponse: + Response object for ``ListTeamsRequest`` containing + matching ``Team`` objects. + + """ + + http_options = ( + _BaseTeamServiceRestTransport._BaseListTeams._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_teams(request, metadata) + transcoded_request = ( + _BaseTeamServiceRestTransport._BaseListTeams._get_transcoded_request( + http_options, request + ) + ) + + # Jsonify the query params + query_params = ( + _BaseTeamServiceRestTransport._BaseListTeams._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.TeamServiceClient.ListTeams", + extra={ + "serviceName": "google.ads.admanager.v1.TeamService", + "rpcName": "ListTeams", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = TeamServiceRestTransport._ListTeams._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = team_service.ListTeamsResponse() + pb_resp = team_service.ListTeamsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_teams(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_teams_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = team_service.ListTeamsResponse.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.TeamServiceClient.list_teams", + extra={ + "serviceName": "google.ads.admanager.v1.TeamService", + "rpcName": "ListTeams", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _UpdateTeam( + _BaseTeamServiceRestTransport._BaseUpdateTeam, TeamServiceRestStub + ): + def __hash__(self): + return hash("TeamServiceRestTransport.UpdateTeam") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: team_service.UpdateTeamRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> team_messages.Team: + r"""Call the update team method over HTTP. + + Args: + request (~.team_service.UpdateTeamRequest): + The request object. Request object for ``UpdateTeam`` method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.team_messages.Team: + A Team defines a grouping of users + and what entities they have access to. + + """ + + http_options = ( + _BaseTeamServiceRestTransport._BaseUpdateTeam._get_http_options() + ) + + request, metadata = self._interceptor.pre_update_team(request, metadata) + transcoded_request = ( + _BaseTeamServiceRestTransport._BaseUpdateTeam._get_transcoded_request( + http_options, request + ) + ) + + body = _BaseTeamServiceRestTransport._BaseUpdateTeam._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = ( + _BaseTeamServiceRestTransport._BaseUpdateTeam._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.TeamServiceClient.UpdateTeam", + extra={ + "serviceName": "google.ads.admanager.v1.TeamService", + "rpcName": "UpdateTeam", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = TeamServiceRestTransport._UpdateTeam._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = team_messages.Team() + pb_resp = team_messages.Team.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_update_team(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_team_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = team_messages.Team.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.TeamServiceClient.update_team", + extra={ + "serviceName": "google.ads.admanager.v1.TeamService", + "rpcName": "UpdateTeam", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def batch_activate_teams( + self, + ) -> Callable[ + [team_service.BatchActivateTeamsRequest], + team_service.BatchActivateTeamsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchActivateTeams(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_create_teams( + self, + ) -> Callable[ + [team_service.BatchCreateTeamsRequest], team_service.BatchCreateTeamsResponse + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchCreateTeams(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_deactivate_teams( + self, + ) -> Callable[ + [team_service.BatchDeactivateTeamsRequest], + team_service.BatchDeactivateTeamsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchDeactivateTeams(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_update_teams( + self, + ) -> Callable[ + [team_service.BatchUpdateTeamsRequest], team_service.BatchUpdateTeamsResponse + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BatchUpdateTeams(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_team( + self, + ) -> Callable[[team_service.CreateTeamRequest], team_messages.Team]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateTeam(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_team(self) -> Callable[[team_service.GetTeamRequest], team_messages.Team]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetTeam(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_teams( + self, + ) -> Callable[[team_service.ListTeamsRequest], team_service.ListTeamsResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListTeams(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_team( + self, + ) -> Callable[[team_service.UpdateTeamRequest], team_messages.Team]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateTeam(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseTeamServiceRestTransport._BaseGetOperation, TeamServiceRestStub + ): + def __hash__(self): + return hash("TeamServiceRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = ( + _BaseTeamServiceRestTransport._BaseGetOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = ( + _BaseTeamServiceRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + ) + + # Jsonify the query params + query_params = ( + _BaseTeamServiceRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.ads.admanager_v1.TeamServiceClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.TeamService", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = TeamServiceRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.ads.admanager_v1.TeamServiceAsyncClient.GetOperation", + extra={ + "serviceName": "google.ads.admanager.v1.TeamService", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("TeamServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/transports/rest_base.py b/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/transports/rest_base.py new file mode 100644 index 000000000000..fef918b1e8ea --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/services/team_service/transports/rest_base.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 json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import json_format + +from google.ads.admanager_v1.types import team_messages, team_service + +from .base import DEFAULT_CLIENT_INFO, TeamServiceTransport + + +class _BaseTeamServiceRestTransport(TeamServiceTransport): + """Base REST backend transport for TeamService. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "admanager.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'admanager.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseBatchActivateTeams: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/teams:batchActivate", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = team_service.BatchActivateTeamsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseTeamServiceRestTransport._BaseBatchActivateTeams._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseBatchCreateTeams: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/teams:batchCreate", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = team_service.BatchCreateTeamsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseTeamServiceRestTransport._BaseBatchCreateTeams._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseBatchDeactivateTeams: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/teams:batchDeactivate", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = team_service.BatchDeactivateTeamsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseTeamServiceRestTransport._BaseBatchDeactivateTeams._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseBatchUpdateTeams: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/teams:batchUpdate", + "body": "*", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = team_service.BatchUpdateTeamsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseTeamServiceRestTransport._BaseBatchUpdateTeams._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseCreateTeam: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{parent=networks/*}/teams", + "body": "team", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = team_service.CreateTeamRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseTeamServiceRestTransport._BaseCreateTeam._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetTeam: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/teams/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = team_service.GetTeamRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseTeamServiceRestTransport._BaseGetTeam._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListTeams: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=networks/*}/teams", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = team_service.ListTeamsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseTeamServiceRestTransport._BaseListTeams._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateTeam: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "updateMask": {}, + } + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v1/{team.name=networks/*/teams/*}", + "body": "team", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = team_service.UpdateTeamRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseTeamServiceRestTransport._BaseUpdateTeam._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=networks/*/operations/reports/runs/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseTeamServiceRestTransport",) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/__init__.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/__init__.py index 6cb0520e33c1..c65f2219ba10 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/__init__.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/__init__.py @@ -22,6 +22,17 @@ ListAdBreaksResponse, UpdateAdBreakRequest, ) +from .ad_review_center_ad_enums import AdReviewCenterAdStatusEnum +from .ad_review_center_ad_messages import AdReviewCenterAd +from .ad_review_center_ad_service import ( + BatchAdReviewCenterAdsOperationMetadata, + BatchAllowAdReviewCenterAdsRequest, + BatchAllowAdReviewCenterAdsResponse, + BatchBlockAdReviewCenterAdsRequest, + BatchBlockAdReviewCenterAdsResponse, + SearchAdReviewCenterAdsRequest, + SearchAdReviewCenterAdsResponse, +) from .ad_unit_enums import AdUnitStatusEnum, SmartSizeModeEnum, TargetWindowEnum from .ad_unit_messages import AdUnit, AdUnitParent, AdUnitSize, LabelFrequencyCap from .ad_unit_service import ( @@ -32,13 +43,51 @@ ListAdUnitsResponse, ) from .admanager_error import AdManagerError +from .application_messages import Application +from .application_service import ( + GetApplicationRequest, + ListApplicationsRequest, + ListApplicationsResponse, +) from .applied_label import AppliedLabel +from .audience_segment_messages import AudienceSegment +from .audience_segment_service import ( + GetAudienceSegmentRequest, + ListAudienceSegmentsRequest, + ListAudienceSegmentsResponse, +) from .bandwidth_group_messages import BandwidthGroup from .bandwidth_group_service import ( GetBandwidthGroupRequest, ListBandwidthGroupsRequest, ListBandwidthGroupsResponse, ) +from .browser_language_messages import BrowserLanguage +from .browser_language_service import ( + GetBrowserLanguageRequest, + ListBrowserLanguagesRequest, + ListBrowserLanguagesResponse, +) +from .browser_messages import Browser +from .browser_service import ( + GetBrowserRequest, + ListBrowsersRequest, + ListBrowsersResponse, +) +from .cms_metadata_key_enums import CmsMetadataKeyStatusEnum +from .cms_metadata_key_messages import CmsMetadataKey +from .cms_metadata_key_service import ( + GetCmsMetadataKeyRequest, + ListCmsMetadataKeysRequest, + ListCmsMetadataKeysResponse, +) +from .cms_metadata_value_enums import CmsMetadataValueStatusEnum +from .cms_metadata_value_messages import CmsMetadataValue +from .cms_metadata_value_service import ( + GetCmsMetadataValueRequest, + ListCmsMetadataValuesRequest, + ListCmsMetadataValuesResponse, +) from .company_enums import CompanyCreditStatusEnum, CompanyTypeEnum from .company_messages import Company from .company_service import ( @@ -46,7 +95,46 @@ ListCompaniesRequest, ListCompaniesResponse, ) +from .contact_enums import ContactStatusEnum from .contact_messages import Contact +from .contact_service import ( + BatchCreateContactsRequest, + BatchCreateContactsResponse, + BatchUpdateContactsRequest, + BatchUpdateContactsResponse, + CreateContactRequest, + GetContactRequest, + ListContactsRequest, + ListContactsResponse, + UpdateContactRequest, +) +from .content_bundle_messages import ContentBundle +from .content_bundle_service import ( + GetContentBundleRequest, + ListContentBundlesRequest, + ListContentBundlesResponse, +) +from .content_label_messages import ContentLabel +from .content_label_service import ( + GetContentLabelRequest, + ListContentLabelsRequest, + ListContentLabelsResponse, +) +from .content_messages import Content +from .content_service import GetContentRequest, ListContentRequest, ListContentResponse +from .creative_template_enums import ( + CreativeTemplateStatusEnum, + CreativeTemplateTypeEnum, +) +from .creative_template_messages import CreativeTemplate, CreativeTemplateVariable +from .creative_template_service import ( + GetCreativeTemplateRequest, + ListCreativeTemplatesRequest, + ListCreativeTemplatesResponse, +) +from .creative_template_variable_url_type_enum import ( + CreativeTemplateVariableUrlTypeEnum, +) from .custom_field_enums import ( CustomFieldDataTypeEnum, CustomFieldEntityTypeEnum, @@ -55,9 +143,19 @@ ) from .custom_field_messages import CustomField, CustomFieldOption from .custom_field_service import ( + BatchActivateCustomFieldsRequest, + BatchActivateCustomFieldsResponse, + BatchCreateCustomFieldsRequest, + BatchCreateCustomFieldsResponse, + BatchDeactivateCustomFieldsRequest, + BatchDeactivateCustomFieldsResponse, + BatchUpdateCustomFieldsRequest, + BatchUpdateCustomFieldsResponse, + CreateCustomFieldRequest, GetCustomFieldRequest, ListCustomFieldsRequest, ListCustomFieldsResponse, + UpdateCustomFieldRequest, ) from .custom_field_value import CustomFieldValue from .custom_targeting_key_enums import ( @@ -82,12 +180,24 @@ ListCustomTargetingValuesResponse, ) from .deal_buyer_permission_type_enum import DealBuyerPermissionTypeEnum +from .device_capability_messages import DeviceCapability +from .device_capability_service import ( + GetDeviceCapabilityRequest, + ListDeviceCapabilitiesRequest, + ListDeviceCapabilitiesResponse, +) from .device_category_messages import DeviceCategory from .device_category_service import ( GetDeviceCategoryRequest, ListDeviceCategoriesRequest, ListDeviceCategoriesResponse, ) +from .device_manufacturer_messages import DeviceManufacturer +from .device_manufacturer_service import ( + GetDeviceManufacturerRequest, + ListDeviceManufacturersRequest, + ListDeviceManufacturersResponse, +) from .early_ad_break_notification_enums import AdBreakStateEnum from .entity_signals_mapping_messages import EntitySignalsMapping from .entity_signals_mapping_service import ( @@ -102,6 +212,7 @@ UpdateEntitySignalsMappingRequest, ) from .environment_type_enum import EnvironmentTypeEnum +from .exchange_syndication_product_enum import ExchangeSyndicationProductEnum from .frequency_cap import FrequencyCap from .geo_target_messages import GeoTarget from .geo_target_service import ( @@ -111,6 +222,24 @@ ) from .label_messages import Label from .live_stream_event_messages import LiveStreamEvent +from .mobile_carrier_messages import MobileCarrier +from .mobile_carrier_service import ( + GetMobileCarrierRequest, + ListMobileCarriersRequest, + ListMobileCarriersResponse, +) +from .mobile_device_messages import MobileDevice +from .mobile_device_service import ( + GetMobileDeviceRequest, + ListMobileDevicesRequest, + ListMobileDevicesResponse, +) +from .mobile_device_submodel_messages import MobileDeviceSubmodel +from .mobile_device_submodel_service import ( + GetMobileDeviceSubmodelRequest, + ListMobileDeviceSubmodelsRequest, + ListMobileDeviceSubmodelsResponse, +) from .network_messages import Network from .network_service import ( GetNetworkRequest, @@ -135,9 +264,21 @@ from .placement_enums import PlacementStatusEnum from .placement_messages import Placement from .placement_service import ( + BatchActivatePlacementsRequest, + BatchActivatePlacementsResponse, + BatchArchivePlacementsRequest, + BatchArchivePlacementsResponse, + BatchCreatePlacementsRequest, + BatchCreatePlacementsResponse, + BatchDeactivatePlacementsRequest, + BatchDeactivatePlacementsResponse, + BatchUpdatePlacementsRequest, + BatchUpdatePlacementsResponse, + CreatePlacementRequest, GetPlacementRequest, ListPlacementsRequest, ListPlacementsResponse, + UpdatePlacementRequest, ) from .private_auction_deal_messages import PrivateAuctionDeal from .private_auction_deal_service import ( @@ -162,7 +303,8 @@ ListProgrammaticBuyersRequest, ListProgrammaticBuyersResponse, ) -from .report_messages import Report, ReportDefinition, Schedule, ScheduleOptions +from .report_definition import ReportDefinition +from .report_messages import Report, ReportDataTable, ScheduleOptions from .report_service import ( CreateReportRequest, FetchReportResultRowsRequest, @@ -175,23 +317,51 @@ RunReportResponse, UpdateReportRequest, ) +from .report_value import ReportValue from .request_platform_enum import RequestPlatformEnum from .role_enums import RoleStatusEnum from .role_messages import Role from .role_service import GetRoleRequest, ListRolesRequest, ListRolesResponse +from .site_enums import SiteApprovalStatusEnum, SiteDisapprovalReasonEnum +from .site_messages import DisapprovalReason, Site +from .site_service import ( + BatchCreateSitesRequest, + BatchCreateSitesResponse, + BatchDeactivateSitesRequest, + BatchDeactivateSitesResponse, + BatchSubmitSitesForApprovalRequest, + BatchSubmitSitesForApprovalResponse, + BatchUpdateSitesRequest, + BatchUpdateSitesResponse, + CreateSiteRequest, + GetSiteRequest, + ListSitesRequest, + ListSitesResponse, + UpdateSiteRequest, +) from .size import Size from .size_type_enum import SizeTypeEnum from .targeted_video_bumper_type_enum import TargetedVideoBumperTypeEnum from .targeting import ( AdUnitTargeting, + AudienceSegmentTargeting, BandwidthTargeting, + BrowserLanguageTargeting, + BrowserTargeting, + CmsMetadataTargeting, + ContentTargeting, CustomTargeting, CustomTargetingClause, CustomTargetingLiteral, DataSegmentTargeting, + DeviceCapabilityTargeting, DeviceCategoryTargeting, + DeviceManufacturerTargeting, + FirstPartyMobileApplicationTargeting, GeoTargeting, InventoryTargeting, + MobileApplicationTargeting, + MobileCarrierTargeting, OperatingSystemTargeting, RequestPlatformTargeting, Targeting, @@ -207,11 +377,28 @@ ListTaxonomyCategoriesResponse, ) from .taxonomy_type_enum import TaxonomyTypeEnum +from .team_enums import TeamAccessTypeEnum, TeamStatusEnum from .team_messages import Team +from .team_service import ( + BatchActivateTeamsRequest, + BatchActivateTeamsResponse, + BatchCreateTeamsRequest, + BatchCreateTeamsResponse, + BatchDeactivateTeamsRequest, + BatchDeactivateTeamsResponse, + BatchUpdateTeamsRequest, + BatchUpdateTeamsResponse, + CreateTeamRequest, + GetTeamRequest, + ListTeamsRequest, + ListTeamsResponse, + UpdateTeamRequest, +) from .time_unit_enum import TimeUnitEnum from .user_messages import User from .user_service import GetUserRequest from .video_position_enum import VideoPositionEnum +from .web_property import WebProperty __all__ = ( "AdBreak", @@ -221,6 +408,15 @@ "ListAdBreaksRequest", "ListAdBreaksResponse", "UpdateAdBreakRequest", + "AdReviewCenterAdStatusEnum", + "AdReviewCenterAd", + "BatchAdReviewCenterAdsOperationMetadata", + "BatchAllowAdReviewCenterAdsRequest", + "BatchAllowAdReviewCenterAdsResponse", + "BatchBlockAdReviewCenterAdsRequest", + "BatchBlockAdReviewCenterAdsResponse", + "SearchAdReviewCenterAdsRequest", + "SearchAdReviewCenterAdsResponse", "AdUnitStatusEnum", "SmartSizeModeEnum", "TargetWindowEnum", @@ -234,27 +430,93 @@ "ListAdUnitsRequest", "ListAdUnitsResponse", "AdManagerError", + "Application", + "GetApplicationRequest", + "ListApplicationsRequest", + "ListApplicationsResponse", "AppliedLabel", + "AudienceSegment", + "GetAudienceSegmentRequest", + "ListAudienceSegmentsRequest", + "ListAudienceSegmentsResponse", "BandwidthGroup", "GetBandwidthGroupRequest", "ListBandwidthGroupsRequest", "ListBandwidthGroupsResponse", + "BrowserLanguage", + "GetBrowserLanguageRequest", + "ListBrowserLanguagesRequest", + "ListBrowserLanguagesResponse", + "Browser", + "GetBrowserRequest", + "ListBrowsersRequest", + "ListBrowsersResponse", + "CmsMetadataKeyStatusEnum", + "CmsMetadataKey", + "GetCmsMetadataKeyRequest", + "ListCmsMetadataKeysRequest", + "ListCmsMetadataKeysResponse", + "CmsMetadataValueStatusEnum", + "CmsMetadataValue", + "GetCmsMetadataValueRequest", + "ListCmsMetadataValuesRequest", + "ListCmsMetadataValuesResponse", "CompanyCreditStatusEnum", "CompanyTypeEnum", "Company", "GetCompanyRequest", "ListCompaniesRequest", "ListCompaniesResponse", + "ContactStatusEnum", "Contact", + "BatchCreateContactsRequest", + "BatchCreateContactsResponse", + "BatchUpdateContactsRequest", + "BatchUpdateContactsResponse", + "CreateContactRequest", + "GetContactRequest", + "ListContactsRequest", + "ListContactsResponse", + "UpdateContactRequest", + "ContentBundle", + "GetContentBundleRequest", + "ListContentBundlesRequest", + "ListContentBundlesResponse", + "ContentLabel", + "GetContentLabelRequest", + "ListContentLabelsRequest", + "ListContentLabelsResponse", + "Content", + "GetContentRequest", + "ListContentRequest", + "ListContentResponse", + "CreativeTemplateStatusEnum", + "CreativeTemplateTypeEnum", + "CreativeTemplate", + "CreativeTemplateVariable", + "GetCreativeTemplateRequest", + "ListCreativeTemplatesRequest", + "ListCreativeTemplatesResponse", + "CreativeTemplateVariableUrlTypeEnum", "CustomFieldDataTypeEnum", "CustomFieldEntityTypeEnum", "CustomFieldStatusEnum", "CustomFieldVisibilityEnum", "CustomField", "CustomFieldOption", + "BatchActivateCustomFieldsRequest", + "BatchActivateCustomFieldsResponse", + "BatchCreateCustomFieldsRequest", + "BatchCreateCustomFieldsResponse", + "BatchDeactivateCustomFieldsRequest", + "BatchDeactivateCustomFieldsResponse", + "BatchUpdateCustomFieldsRequest", + "BatchUpdateCustomFieldsResponse", + "CreateCustomFieldRequest", "GetCustomFieldRequest", "ListCustomFieldsRequest", "ListCustomFieldsResponse", + "UpdateCustomFieldRequest", "CustomFieldValue", "CustomTargetingKeyReportableTypeEnum", "CustomTargetingKeyStatusEnum", @@ -270,10 +532,18 @@ "ListCustomTargetingValuesRequest", "ListCustomTargetingValuesResponse", "DealBuyerPermissionTypeEnum", + "DeviceCapability", + "GetDeviceCapabilityRequest", + "ListDeviceCapabilitiesRequest", + "ListDeviceCapabilitiesResponse", "DeviceCategory", "GetDeviceCategoryRequest", "ListDeviceCategoriesRequest", "ListDeviceCategoriesResponse", + "DeviceManufacturer", + "GetDeviceManufacturerRequest", + "ListDeviceManufacturersRequest", + "ListDeviceManufacturersResponse", "AdBreakStateEnum", "EntitySignalsMapping", "BatchCreateEntitySignalsMappingsRequest", @@ -286,6 +556,7 @@ "ListEntitySignalsMappingsResponse", "UpdateEntitySignalsMappingRequest", "EnvironmentTypeEnum", + "ExchangeSyndicationProductEnum", "FrequencyCap", "GeoTarget", "GetGeoTargetRequest", @@ -293,6 +564,18 @@ "ListGeoTargetsResponse", "Label", "LiveStreamEvent", + "MobileCarrier", + "GetMobileCarrierRequest", + "ListMobileCarriersRequest", + "ListMobileCarriersResponse", + "MobileDevice", + "GetMobileDeviceRequest", + "ListMobileDevicesRequest", + "ListMobileDevicesResponse", + "MobileDeviceSubmodel", + "GetMobileDeviceSubmodelRequest", + "ListMobileDeviceSubmodelsRequest", + "ListMobileDeviceSubmodelsResponse", "Network", "GetNetworkRequest", "ListNetworksRequest", @@ -312,9 +595,21 @@ "ListOrdersResponse", "PlacementStatusEnum", "Placement", + "BatchActivatePlacementsRequest", + "BatchActivatePlacementsResponse", + "BatchArchivePlacementsRequest", + "BatchArchivePlacementsResponse", + "BatchCreatePlacementsRequest", + "BatchCreatePlacementsResponse", + "BatchDeactivatePlacementsRequest", + "BatchDeactivatePlacementsResponse", + "BatchUpdatePlacementsRequest", + "BatchUpdatePlacementsResponse", + "CreatePlacementRequest", "GetPlacementRequest", "ListPlacementsRequest", "ListPlacementsResponse", + "UpdatePlacementRequest", "PrivateAuctionDeal", "CreatePrivateAuctionDealRequest", "GetPrivateAuctionDealRequest", @@ -332,9 +627,9 @@ "GetProgrammaticBuyerRequest", "ListProgrammaticBuyersRequest", "ListProgrammaticBuyersResponse", - "Report", "ReportDefinition", - "Schedule", + "Report", + "ReportDataTable", "ScheduleOptions", "CreateReportRequest", "FetchReportResultRowsRequest", @@ -346,24 +641,52 @@ "RunReportRequest", "RunReportResponse", "UpdateReportRequest", + "ReportValue", "RequestPlatformEnum", "RoleStatusEnum", "Role", "GetRoleRequest", "ListRolesRequest", "ListRolesResponse", + "SiteApprovalStatusEnum", + "SiteDisapprovalReasonEnum", + "DisapprovalReason", + "Site", + "BatchCreateSitesRequest", + "BatchCreateSitesResponse", + "BatchDeactivateSitesRequest", + "BatchDeactivateSitesResponse", + "BatchSubmitSitesForApprovalRequest", + "BatchSubmitSitesForApprovalResponse", + "BatchUpdateSitesRequest", + "BatchUpdateSitesResponse", + "CreateSiteRequest", + "GetSiteRequest", + "ListSitesRequest", + "ListSitesResponse", + "UpdateSiteRequest", "Size", "SizeTypeEnum", "TargetedVideoBumperTypeEnum", "AdUnitTargeting", + "AudienceSegmentTargeting", "BandwidthTargeting", + "BrowserLanguageTargeting", + "BrowserTargeting", + "CmsMetadataTargeting", + "ContentTargeting", "CustomTargeting", "CustomTargetingClause", "CustomTargetingLiteral", "DataSegmentTargeting", + "DeviceCapabilityTargeting", "DeviceCategoryTargeting", + "DeviceManufacturerTargeting", + "FirstPartyMobileApplicationTargeting", "GeoTargeting", "InventoryTargeting", + "MobileApplicationTargeting", + "MobileCarrierTargeting", "OperatingSystemTargeting", "RequestPlatformTargeting", "Targeting", @@ -376,9 +699,25 @@ "ListTaxonomyCategoriesRequest", "ListTaxonomyCategoriesResponse", "TaxonomyTypeEnum", + "TeamAccessTypeEnum", + "TeamStatusEnum", "Team", + "BatchActivateTeamsRequest", + "BatchActivateTeamsResponse", + "BatchCreateTeamsRequest", + "BatchCreateTeamsResponse", + "BatchDeactivateTeamsRequest", + "BatchDeactivateTeamsResponse", + "BatchUpdateTeamsRequest", + "BatchUpdateTeamsResponse", + "CreateTeamRequest", + "GetTeamRequest", + "ListTeamsRequest", + "ListTeamsResponse", + "UpdateTeamRequest", "TimeUnitEnum", "User", "GetUserRequest", "VideoPositionEnum", + "WebProperty", ) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/ad_break_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/ad_break_service.py index 2a9354c3825b..605ac5b8160c 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/ad_break_service.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/ad_break_service.py @@ -133,8 +133,8 @@ class ListAdBreaksResponse(proto.Message): included in the request, this reflects the total number after the filtering is applied. - ``total_size`` will not be calculated in the response unless - it has been included in a response field mask. The response + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response field mask can be provided to the method by using the URL parameter ``$fields`` or ``fields``, or by using the HTTP/gRPC header ``X-Goog-FieldMask``. diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/ad_review_center_ad_enums.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/ad_review_center_ad_enums.py new file mode 100644 index 000000000000..6c39673c5e7d --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/ad_review_center_ad_enums.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 + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "AdReviewCenterAdStatusEnum", + }, +) + + +class AdReviewCenterAdStatusEnum(proto.Message): + r"""Wrapper message for + [AdReviewCenterAdStatus][google.ads.admanager.v1.AdReviewCenterAdStatusEnum.AdReviewCenterAdStatus] + + """ + + class AdReviewCenterAdStatus(proto.Enum): + r"""Specifies the status of an AdReviewCenterAd. + + Values: + AD_REVIEW_CENTER_AD_STATUS_UNSPECIFIED (0): + Not specified value + ALLOWED (1): + This ad has been explicitly allowed to serve. + BLOCKED (2): + This ad has been explicitly blocked from + serving. + UNREVIEWED (3): + This ad is allowed to serve by default and + has not been reviewed. + """ + AD_REVIEW_CENTER_AD_STATUS_UNSPECIFIED = 0 + ALLOWED = 1 + BLOCKED = 2 + UNREVIEWED = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/ad_review_center_ad_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/ad_review_center_ad_messages.py new file mode 100644 index 000000000000..efab8100bad8 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/ad_review_center_ad_messages.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +from google.ads.admanager_v1.types import ( + ad_review_center_ad_enums, + exchange_syndication_product_enum, +) + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "AdReviewCenterAd", + }, +) + + +class AdReviewCenterAd(proto.Message): + r"""Represents an ad that can be acted on or viewed in the Ad Review + Center. + [AdReviewCenterAd][google.ads.admanager.v1.AdReviewCenterAd]. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + Identifier. The resource name of the AdReviewCenterAd. + Format: + ``networks/{network_code}/webProperties/{web_property_code}/adReviewCenterAds/{ad_review_center_ad_id}`` + ad_review_center_ad_id (str): + Output only. ``AdReviewCenterAd`` ID. + product_type (google.ads.admanager_v1.types.ExchangeSyndicationProductEnum.ExchangeSyndicationProduct): + Output only. Specifies the + ExchangeSyndicationProduct for this + AdReviewCenterAd. + status (google.ads.admanager_v1.types.AdReviewCenterAdStatusEnum.AdReviewCenterAdStatus): + The status of the AdReviewCenterAd. + preview_url (str): + Output only. The preview URL that can be + embedded or accessed directly which will present + the rendered contents of the ad. (This URL + expires 72 hours after being retrieved.). + + This field is a member of `oneof`_ ``_preview_url``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + ad_review_center_ad_id: str = proto.Field( + proto.STRING, + number=2, + ) + product_type: exchange_syndication_product_enum.ExchangeSyndicationProductEnum.ExchangeSyndicationProduct = proto.Field( + proto.ENUM, + number=3, + enum=exchange_syndication_product_enum.ExchangeSyndicationProductEnum.ExchangeSyndicationProduct, + ) + status: ad_review_center_ad_enums.AdReviewCenterAdStatusEnum.AdReviewCenterAdStatus = proto.Field( + proto.ENUM, + number=4, + enum=ad_review_center_ad_enums.AdReviewCenterAdStatusEnum.AdReviewCenterAdStatus, + ) + preview_url: str = proto.Field( + proto.STRING, + number=5, + optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/ad_review_center_ad_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/ad_review_center_ad_service.py new file mode 100644 index 000000000000..f2186add021c --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/ad_review_center_ad_service.py @@ -0,0 +1,271 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +from google.rpc import status_pb2 # type: ignore +from google.type import interval_pb2 # type: ignore +import proto # type: ignore + +from google.ads.admanager_v1.types import ( + ad_review_center_ad_enums, + ad_review_center_ad_messages, +) + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "SearchAdReviewCenterAdsRequest", + "SearchAdReviewCenterAdsResponse", + "BatchAllowAdReviewCenterAdsRequest", + "BatchAllowAdReviewCenterAdsResponse", + "BatchBlockAdReviewCenterAdsRequest", + "BatchBlockAdReviewCenterAdsResponse", + "BatchAdReviewCenterAdsOperationMetadata", + }, +) + + +class SearchAdReviewCenterAdsRequest(proto.Message): + r"""Request object for ``SearchAdReviewCenterAds`` method. + + Attributes: + parent (str): + Required. The parent, which owns this collection of + AdReviewCenterAds. Format: + networks/{network_code}/webProperties/{web_property_code} + + Since a network can only have a single web property of each + ``ExchangeSyndicationProduct``, you can use the + ``ExchangeSyndicationProduct`` as an alias for the web + property code: + + ``networks/{network_code}/webProperties/display`` + + ``networks/{network_code}/webProperties/videoAndAudio`` + + ``networks/{network_code}/webProperties/mobileApp`` + + ``networks/{network_code}/webProperties/games`` + page_size (int): + Optional. The maximum number of + AdReviewCenterAds to return. The service may + return fewer than this value. If unspecified, at + most 50 AdReviewCenterAds will be returned. The + maximum value is 1000; values greater than 1000 + will be coerced to 1000. + page_token (str): + Optional. The page token to fetch the next + page of AdReviewCenterAds. This is the value + returned from a previous Search request, or + empty. + status (google.ads.admanager_v1.types.AdReviewCenterAdStatusEnum.AdReviewCenterAdStatus): + Required. Only return ads with the given + status. + ad_review_center_ad_id (MutableSequence[str]): + Optional. If provided, only return ads with + the given AdReviewCenterAd IDs. + date_time_range (google.type.interval_pb2.Interval): + Optional. If provided, only return ads that + served within the given date range (inclusive). + The date range must be within the last 30 days. + If not provided, the date range will be the last + 30 days. + search_text (MutableSequence[str]): + Optional. If provided, restrict the search to + AdReviewCenterAds associated with the text (including any + text on the ad or in the destination URL). If more than one + value is provided, the search will combine them in a logical + AND. For example, ['car', 'blue'] will match ads that + contain both "car" and "blue", but not an ad that only + contains "car". + buyer_account_id (MutableSequence[int]): + Optional. If provided, restrict the search to + creatives belonging to one of the given Adx + buyer account IDs. Only applicable to RTB + creatives. Adx buyer account IDs can be found + via the ProgrammaticBuyerService. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + status: ad_review_center_ad_enums.AdReviewCenterAdStatusEnum.AdReviewCenterAdStatus = proto.Field( + proto.ENUM, + number=4, + enum=ad_review_center_ad_enums.AdReviewCenterAdStatusEnum.AdReviewCenterAdStatus, + ) + ad_review_center_ad_id: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + date_time_range: interval_pb2.Interval = proto.Field( + proto.MESSAGE, + number=6, + message=interval_pb2.Interval, + ) + search_text: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=7, + ) + buyer_account_id: MutableSequence[int] = proto.RepeatedField( + proto.INT64, + number=8, + ) + + +class SearchAdReviewCenterAdsResponse(proto.Message): + r"""Response object for ``SearchAdReviewCenterAds`` method. + + Attributes: + ad_review_center_ads (MutableSequence[google.ads.admanager_v1.types.AdReviewCenterAd]): + The AdReviewCenterAds that match the search + request. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + """ + + @property + def raw_page(self): + return self + + ad_review_center_ads: MutableSequence[ + ad_review_center_ad_messages.AdReviewCenterAd + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=ad_review_center_ad_messages.AdReviewCenterAd, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class BatchAllowAdReviewCenterAdsRequest(proto.Message): + r"""Request object for ``BatchAllowAdReviewCenterAds`` method. + + Attributes: + parent (str): + Required. The parent, which owns this collection of + AdReviewCenterAds. Format: + networks/{network_code}/webProperties/{web_property_code} + + Since a network can only have a single web property of each + ``ExchangeSyndicationProduct``, you can use the + ``ExchangeSyndicationProduct`` as an alias for the web + property code: + + ``networks/{network_code}/webProperties/display`` + + ``networks/{network_code}/webProperties/videoAndAudio`` + + ``networks/{network_code}/webProperties/mobileApp`` + + ``networks/{network_code}/webProperties/games`` + names (MutableSequence[str]): + Required. The resource names of the ``AdReviewCenterAd``\ s + to allow. Format: + ``networks/{network_code}/webProperties/{web_property_code}/adReviewCenterAds/{ad_review_center_ad_id}`` + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class BatchAllowAdReviewCenterAdsResponse(proto.Message): + r"""Response object for ``BatchAllowAdReviewCenterAds`` method.""" + + +class BatchBlockAdReviewCenterAdsRequest(proto.Message): + r"""Request object for ``BatchBlockAdReviewCenterAds`` method. + + Attributes: + parent (str): + Required. The parent, which owns this collection of + AdReviewCenterAds. Format: + networks/{network_code}/webProperties/{web_property_code} + + Since a network can only have a single web property of each + ``ExchangeSyndicationProduct``, you can use the + ``ExchangeSyndicationProduct`` as an alias for the web + property code: + + ``networks/{network_code}/webProperties/display`` + + ``networks/{network_code}/webProperties/videoAndAudio`` + + ``networks/{network_code}/webProperties/mobileApp`` + + ``networks/{network_code}/webProperties/games`` + names (MutableSequence[str]): + Required. The resource names of the ``AdReviewCenterAd``\ s + to block. Format: + ``networks/{network_code}/webProperties/{web_property_code}/adReviewCenterAds/{ad_review_center_ad_id}`` + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class BatchBlockAdReviewCenterAdsResponse(proto.Message): + r"""Response object for ``BatchBlockAdReviewCenterAds`` method.""" + + +class BatchAdReviewCenterAdsOperationMetadata(proto.Message): + r"""Metadata object for ``BatchAllowAdReviewCenterAds`` and + ``BatchBlockAdReviewCenterAds`` methods. + + Attributes: + failed_requests (MutableMapping[int, google.rpc.status_pb2.Status]): + The status of each failed request, keyed by + the index of the corresponding request in the + batch request. + """ + + failed_requests: MutableMapping[int, status_pb2.Status] = proto.MapField( + proto.INT32, + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/ad_unit_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/ad_unit_messages.py index 3e611419889c..e18306797e07 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/ad_unit_messages.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/ad_unit_messages.py @@ -325,11 +325,18 @@ class AdUnitSize(proto.Message): r"""Represents the size, environment, and companions of an ad in an ad unit. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: size (google.ads.admanager_v1.types.Size): Required. The Size of the AdUnit. + + This field is a member of `oneof`_ ``_size``. environment_type (google.ads.admanager_v1.types.EnvironmentTypeEnum.EnvironmentType): Required. The EnvironmentType of the AdUnit + + This field is a member of `oneof`_ ``_environment_type``. companions (MutableSequence[google.ads.admanager_v1.types.Size]): The companions for this ad unit size. Companions are only valid if the environment is @@ -339,12 +346,14 @@ class AdUnitSize(proto.Message): size: gaa_size.Size = proto.Field( proto.MESSAGE, number=1, + optional=True, message=gaa_size.Size, ) environment_type: environment_type_enum.EnvironmentTypeEnum.EnvironmentType = ( proto.Field( proto.ENUM, number=2, + optional=True, enum=environment_type_enum.EnvironmentTypeEnum.EnvironmentType, ) ) @@ -358,51 +367,70 @@ class AdUnitSize(proto.Message): class AdUnitParent(proto.Message): r"""The summary of a parent AdUnit. + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: parent_ad_unit (str): Output only. The parent of the current AdUnit Format: ``networks/{network_code}/adUnits/{ad_unit_id}`` + + This field is a member of `oneof`_ ``_parent_ad_unit``. display_name (str): Output only. The display name of the parent AdUnit. + + This field is a member of `oneof`_ ``_display_name``. ad_unit_code (str): Output only. A string used to uniquely identify the ad unit for the purposes of serving the ad. + + This field is a member of `oneof`_ ``_ad_unit_code``. """ parent_ad_unit: str = proto.Field( proto.STRING, number=1, + optional=True, ) display_name: str = proto.Field( proto.STRING, number=2, + optional=True, ) ad_unit_code: str = proto.Field( proto.STRING, number=3, + optional=True, ) class LabelFrequencyCap(proto.Message): r"""Frequency cap using a label. + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: label (str): Required. The label to used for frequency capping. Format: "networks/{network_code}/labels/{label_id}". + + This field is a member of `oneof`_ ``_label``. frequency_cap (google.ads.admanager_v1.types.FrequencyCap): The frequency cap. + + This field is a member of `oneof`_ ``_frequency_cap``. """ label: str = proto.Field( proto.STRING, number=1, + optional=True, ) frequency_cap: gaa_frequency_cap.FrequencyCap = proto.Field( proto.MESSAGE, number=2, + optional=True, message=gaa_frequency_cap.FrequencyCap, ) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/ad_unit_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/ad_unit_service.py index d8f383f2ed31..c5af0eb1d45c 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/ad_unit_service.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/ad_unit_service.py @@ -60,7 +60,7 @@ class ListAdUnitsRequest(proto.Message): return. The service may return fewer than this value. If unspecified, at most 50 ad units will be returned. The maximum value is 1000; values - above 1000 will be coerced to 1000. + greater than 1000 will be coerced to 1000. page_token (str): Optional. A page token, received from a previous ``ListAdUnits`` call. Provide this to retrieve the @@ -124,8 +124,8 @@ class ListAdUnitsResponse(proto.Message): request, this reflects the total number after the filtering is applied. - ``total_size`` will not be calculated in the response unless - it has been included in a response field mask. The response + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response field mask can be provided to the method by using the URL parameter ``$fields`` or ``fields``, or by using the HTTP/gRPC header ``X-Goog-FieldMask``. @@ -165,7 +165,8 @@ class ListAdUnitSizesRequest(proto.Message): to return. The service may return fewer than this value. If unspecified, at most 50 ad unit sizes will be returned. The maximum value is - 1000; values above 1000 will be coerced to 1000. + 1000; values greater than 1000 will be coerced + to 1000. page_token (str): Optional. A page token, received from a previous ``ListAdUnitSizes`` call. Provide this to retrieve the @@ -229,8 +230,8 @@ class ListAdUnitSizesResponse(proto.Message): request, this reflects the total number after the filtering is applied. - ``total_size`` will not be calculated in the response unless - it has been included in a response field mask. The response + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response field mask can be provided to the method by using the URL parameter ``$fields`` or ``fields``, or by using the HTTP/gRPC header ``X-Goog-FieldMask``. diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/application_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/application_messages.py new file mode 100644 index 000000000000..c3e86cf17662 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/application_messages.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 + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "Application", + }, +) + + +class Application(proto.Message): + r"""An application that has been added to or "claimed" by the + network to be used for targeting purposes. These mobile apps can + come from various app stores. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + Identifier. The resource name of the ``Application``. + Format: + ``networks/{network_code}/applications/{application_id}`` + display_name (str): + Optional. The display name of the + application. This attribute is required and has + a maximum length of 80 characters. + + This field is a member of `oneof`_ ``_display_name``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=4, + optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/application_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/application_service.py new file mode 100644 index 000000000000..66466c2392f6 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/application_service.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +from google.ads.admanager_v1.types import application_messages + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "GetApplicationRequest", + "ListApplicationsRequest", + "ListApplicationsResponse", + }, +) + + +class GetApplicationRequest(proto.Message): + r"""Request object for ``GetApplication`` method. + + Attributes: + name (str): + Required. The resource name of the Application. Format: + ``networks/{network_code}/applications/{application_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListApplicationsRequest(proto.Message): + r"""Request object for ``ListApplications`` method. + + Attributes: + parent (str): + Required. The parent, which owns this collection of + Applications. Format: ``networks/{network_code}`` + page_size (int): + Optional. The maximum number of ``Applications`` to return. + The service may return fewer than this value. If + unspecified, at most 50 ``Applications`` will be returned. + The maximum value is 1000; values greater than 1000 will be + coerced to 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListApplications`` call. Provide this to retrieve the + subsequent page. + + When paginating, all other parameters provided to + ``ListApplications`` must match the call that provided the + page token. + filter (str): + Optional. Expression to filter the response. + See syntax details at + https://developers.google.com/ad-manager/api/beta/filters + order_by (str): + Optional. Expression to specify sorting + order. See syntax details at + https://developers.google.com/ad-manager/api/beta/filters#order + skip (int): + Optional. Number of individual resources to + skip while paginating. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + skip: int = proto.Field( + proto.INT32, + number=6, + ) + + +class ListApplicationsResponse(proto.Message): + r"""Response object for ``ListApplicationsRequest`` containing matching + ``Application`` objects. + + Attributes: + applications (MutableSequence[google.ads.admanager_v1.types.Application]): + The ``Application`` objects from the specified network. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + total_size (int): + Total number of ``Application`` objects. If a filter was + included in the request, this reflects the total number + after the filtering is applied. + + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response + field mask can be provided to the method by using the URL + parameter ``$fields`` or ``fields``, or by using the + HTTP/gRPC header ``X-Goog-FieldMask``. + + For more information, see + https://developers.google.com/ad-manager/api/beta/field-masks + """ + + @property + def raw_page(self): + return self + + applications: MutableSequence[ + application_messages.Application + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=application_messages.Application, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/audience_segment_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/audience_segment_messages.py new file mode 100644 index 000000000000..f3c53057a910 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/audience_segment_messages.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 + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "AudienceSegment", + }, +) + + +class AudienceSegment(proto.Message): + r"""The ``AudienceSegment`` resource. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + Identifier. The resource name of the ``AudienceSegment``. + Format: + ``networks/{network_code}/audienceSegments/{audience_segment_id}`` + The ``audience_segment_id`` may have up to 1 of the + following suffixes: + + - ``~direct`` for directly licensed third-party segments + - ``~global`` for globally licensed third-party segments + display_name (str): + Required. Display name of the ``AudienceSegment``. The + attribute has a maximum length of 255 characters. + + This field is a member of `oneof`_ ``_display_name``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/audience_segment_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/audience_segment_service.py new file mode 100644 index 000000000000..8a3818c7d45a --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/audience_segment_service.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +from google.ads.admanager_v1.types import audience_segment_messages + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "GetAudienceSegmentRequest", + "ListAudienceSegmentsRequest", + "ListAudienceSegmentsResponse", + }, +) + + +class GetAudienceSegmentRequest(proto.Message): + r"""Request object for ``GetAudienceSegment`` method. + + Attributes: + name (str): + Required. The resource name of the AudienceSegment. Format: + ``networks/{network_code}/audienceSegments/{audience_segment_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListAudienceSegmentsRequest(proto.Message): + r"""Request object for ``ListAudienceSegments`` method. + + Attributes: + parent (str): + Required. The parent publisher network associated with these + audience segments. Format: ``networks/{network_code}`` + page_size (int): + Optional. The maximum number of ``AudienceSegments`` to + return. The service may return fewer than this value. If + unspecified, at most 50 ``AudienceSegments`` will be + returned. The maximum value is 1000; values greater than + 1000 will be coerced to 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListAudienceSegments`` call. Provide this to retrieve the + subsequent page. + + When paginating, all other parameters provided to + ``ListAudienceSegments`` must match the call that provided + the page token. + filter (str): + Optional. Expression to filter the response. + See syntax details at + https://developers.google.com/ad-manager/api/beta/filters + order_by (str): + Optional. Expression to specify sorting + order. See syntax details at + https://developers.google.com/ad-manager/api/beta/filters#order + skip (int): + Optional. Number of individual resources to + skip while paginating. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + skip: int = proto.Field( + proto.INT32, + number=6, + ) + + +class ListAudienceSegmentsResponse(proto.Message): + r"""Response object for ``ListAudienceSegmentsRequest`` containing + matching ``AudienceSegment`` objects. + + Attributes: + audience_segments (MutableSequence[google.ads.admanager_v1.types.AudienceSegment]): + The ``AudienceSegment`` objects from the specified network. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + total_size (int): + Total number of ``AudienceSegment`` objects. If a filter was + included in the request, this reflects the total number + after the filtering is applied. + + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response + field mask can be provided to the method by using the URL + parameter ``$fields`` or ``fields``, or by using the + HTTP/gRPC header ``X-Goog-FieldMask``. + + For more information, see + https://developers.google.com/ad-manager/api/beta/field-masks + """ + + @property + def raw_page(self): + return self + + audience_segments: MutableSequence[ + audience_segment_messages.AudienceSegment + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=audience_segment_messages.AudienceSegment, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/bandwidth_group_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/bandwidth_group_service.py index ce2e8e225ebe..da2bcff452fa 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/bandwidth_group_service.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/bandwidth_group_service.py @@ -57,8 +57,8 @@ class ListBandwidthGroupsRequest(proto.Message): Optional. The maximum number of ``BandwidthGroups`` to return. The service may return fewer than this value. If unspecified, at most 50 ``BandwidthGroups`` will be - returned. The maximum value is 1000; values above 1000 will - be coerced to 1000. + returned. The maximum value is 1000; values greater than + 1000 will be coerced to 1000. page_token (str): Optional. A page token, received from a previous ``ListBandwidthGroups`` call. Provide this to retrieve the @@ -122,8 +122,8 @@ class ListBandwidthGroupsResponse(proto.Message): included in the request, this reflects the total number after the filtering is applied. - ``total_size`` will not be calculated in the response unless - it has been included in a response field mask. The response + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response field mask can be provided to the method by using the URL parameter ``$fields`` or ``fields``, or by using the HTTP/gRPC header ``X-Goog-FieldMask``. diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/browser_language_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/browser_language_messages.py new file mode 100644 index 000000000000..1ca7ab8e69a5 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/browser_language_messages.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 + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "BrowserLanguage", + }, +) + + +class BrowserLanguage(proto.Message): + r"""Represents the language of a browser. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + Identifier. The resource name of the ``BrowserLanguage``. + Format: + ``networks/{network_code}/browserLanguages/{browser_language_id}`` + display_name (str): + Output only. The name of the browser + language, localized. + + This field is a member of `oneof`_ ``_display_name``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/browser_language_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/browser_language_service.py new file mode 100644 index 000000000000..9dcc58ecfa08 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/browser_language_service.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +from google.ads.admanager_v1.types import browser_language_messages + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "GetBrowserLanguageRequest", + "ListBrowserLanguagesRequest", + "ListBrowserLanguagesResponse", + }, +) + + +class GetBrowserLanguageRequest(proto.Message): + r"""Request object for ``GetBrowserLanguage`` method. + + Attributes: + name (str): + Required. The resource name of the BrowserLanguage. Format: + ``networks/{network_code}/browserLanguages/{browser_language_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListBrowserLanguagesRequest(proto.Message): + r"""Request object for ``ListBrowserLanguages`` method. + + Attributes: + parent (str): + Required. The parent, which owns this collection of + BrowserLanguages. Format: ``networks/{network_code}`` + page_size (int): + Optional. The maximum number of ``BrowserLanguages`` to + return. The service may return fewer than this value. If + unspecified, at most 50 ``BrowserLanguages`` will be + returned. The maximum value is 1000; values greater than + 1000 will be coerced to 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListBrowserLanguages`` call. Provide this to retrieve the + subsequent page. + + When paginating, all other parameters provided to + ``ListBrowserLanguages`` must match the call that provided + the page token. + filter (str): + Optional. Expression to filter the response. + See syntax details at + https://developers.google.com/ad-manager/api/beta/filters + order_by (str): + Optional. Expression to specify sorting + order. See syntax details at + https://developers.google.com/ad-manager/api/beta/filters#order + skip (int): + Optional. Number of individual resources to + skip while paginating. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + skip: int = proto.Field( + proto.INT32, + number=6, + ) + + +class ListBrowserLanguagesResponse(proto.Message): + r"""Response object for ``ListBrowserLanguagesRequest`` containing + matching ``BrowserLanguage`` objects. + + Attributes: + browser_languages (MutableSequence[google.ads.admanager_v1.types.BrowserLanguage]): + The ``BrowserLanguage`` objects from the specified network. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + total_size (int): + Total number of ``BrowserLanguage`` objects. If a filter was + included in the request, this reflects the total number + after the filtering is applied. + + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response + field mask can be provided to the method by using the URL + parameter ``$fields`` or ``fields``, or by using the + HTTP/gRPC header ``X-Goog-FieldMask``. + + For more information, see + https://developers.google.com/ad-manager/api/beta/field-masks + """ + + @property + def raw_page(self): + return self + + browser_languages: MutableSequence[ + browser_language_messages.BrowserLanguage + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=browser_language_messages.BrowserLanguage, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/browser_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/browser_messages.py new file mode 100644 index 000000000000..7f7db2b087eb --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/browser_messages.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "Browser", + }, +) + + +class Browser(proto.Message): + r"""Represents a browser, including its version. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + Identifier. The resource name of the ``Browser``. Format: + ``networks/{network_code}/browsers/{browser}`` + display_name (str): + Output only. The display name of the browser, + including version info. + + This field is a member of `oneof`_ ``_display_name``. + major_version (str): + Output only. The major version of the + browser. + + This field is a member of `oneof`_ ``_major_version``. + minor_version (str): + Output only. The minor version of the + browser. + + This field is a member of `oneof`_ ``_minor_version``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + major_version: str = proto.Field( + proto.STRING, + number=4, + optional=True, + ) + minor_version: str = proto.Field( + proto.STRING, + number=5, + optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/browser_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/browser_service.py new file mode 100644 index 000000000000..cfae50da1c87 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/browser_service.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +from google.ads.admanager_v1.types import browser_messages + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "GetBrowserRequest", + "ListBrowsersRequest", + "ListBrowsersResponse", + }, +) + + +class GetBrowserRequest(proto.Message): + r"""Request object for ``GetBrowser`` method. + + Attributes: + name (str): + Required. The resource name of the Browser. Format: + ``networks/{network_code}/browsers/{browser_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListBrowsersRequest(proto.Message): + r"""Request object for ``ListBrowsers`` method. + + Attributes: + parent (str): + Required. The parent, which owns this collection of + Browsers. Format: ``networks/{network_code}`` + page_size (int): + Optional. The maximum number of ``Browsers`` to return. The + service may return fewer than this value. If unspecified, at + most 50 ``Browsers`` will be returned. The maximum value is + 1000; values greater than 1000 will be coerced to 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListBrowsers`` call. Provide this to retrieve the + subsequent page. + + When paginating, all other parameters provided to + ``ListBrowsers`` must match the call that provided the page + token. + filter (str): + Optional. Expression to filter the response. + See syntax details at + https://developers.google.com/ad-manager/api/beta/filters + order_by (str): + Optional. Expression to specify sorting + order. See syntax details at + https://developers.google.com/ad-manager/api/beta/filters#order + skip (int): + Optional. Number of individual resources to + skip while paginating. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + skip: int = proto.Field( + proto.INT32, + number=6, + ) + + +class ListBrowsersResponse(proto.Message): + r"""Response object for ``ListBrowsersRequest`` containing matching + ``Browser`` objects. + + Attributes: + browsers (MutableSequence[google.ads.admanager_v1.types.Browser]): + The ``Browser`` objects from the specified network. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + total_size (int): + Total number of ``Browser`` objects. If a filter was + included in the request, this reflects the total number + after the filtering is applied. + + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response + field mask can be provided to the method by using the URL + parameter ``$fields`` or ``fields``, or by using the + HTTP/gRPC header ``X-Goog-FieldMask``. + + For more information, see + https://developers.google.com/ad-manager/api/beta/field-masks + """ + + @property + def raw_page(self): + return self + + browsers: MutableSequence[browser_messages.Browser] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=browser_messages.Browser, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/cms_metadata_key_enums.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/cms_metadata_key_enums.py new file mode 100644 index 000000000000..7dbc67bb2349 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/cms_metadata_key_enums.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "CmsMetadataKeyStatusEnum", + }, +) + + +class CmsMetadataKeyStatusEnum(proto.Message): + r"""Wrapper message for + [CmsMetadataKeyStatus][google.ads.admanager.v1.CmsMetadataKeyStatusEnum.CmsMetadataKeyStatus] + + """ + + class CmsMetadataKeyStatus(proto.Enum): + r"""Status for CmsMetadataKey objects. + + Values: + CMS_METADATA_KEY_STATUS_UNSPECIFIED (0): + Default value. This value is unused. + ACTIVE (1): + The key is active. + INACTIVE (2): + The key is not active. + """ + CMS_METADATA_KEY_STATUS_UNSPECIFIED = 0 + ACTIVE = 1 + INACTIVE = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/cms_metadata_key_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/cms_metadata_key_messages.py new file mode 100644 index 000000000000..7d6f80ce2000 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/cms_metadata_key_messages.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 + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.ads.admanager_v1.types import cms_metadata_key_enums + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "CmsMetadataKey", + }, +) + + +class CmsMetadataKey(proto.Message): + r"""Key associated with a piece of content from a publisher's + CMS. + + Attributes: + name (str): + Identifier. The resource name of the ``CmsMetadataKey``. + Format: + ``networks/{network_code}/cmsMetadataKeys/{cms_metadata_key_id}`` + display_name (str): + Required. The key of a key-value pair. + status (google.ads.admanager_v1.types.CmsMetadataKeyStatusEnum.CmsMetadataKeyStatus): + Output only. The status of this CMS metadata + key. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=3, + ) + status: cms_metadata_key_enums.CmsMetadataKeyStatusEnum.CmsMetadataKeyStatus = ( + proto.Field( + proto.ENUM, + number=4, + enum=cms_metadata_key_enums.CmsMetadataKeyStatusEnum.CmsMetadataKeyStatus, + ) + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/cms_metadata_key_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/cms_metadata_key_service.py new file mode 100644 index 000000000000..cbaaa15d50a3 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/cms_metadata_key_service.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +from google.ads.admanager_v1.types import cms_metadata_key_messages + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "GetCmsMetadataKeyRequest", + "ListCmsMetadataKeysRequest", + "ListCmsMetadataKeysResponse", + }, +) + + +class GetCmsMetadataKeyRequest(proto.Message): + r"""Request object for ``GetCmsMetadataKey`` method. + + Attributes: + name (str): + Required. The resource name of the CmsMetadataKey. Format: + ``networks/{network_code}/cmsMetadataKeys/{cms_metadata_key_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListCmsMetadataKeysRequest(proto.Message): + r"""Request object for ``ListCmsMetadataKeys`` method. + + Attributes: + parent (str): + Required. The parent, which owns this collection of + CmsMetadataKeys. Format: ``networks/{network_code}`` + page_size (int): + Optional. The maximum number of ``CmsMetadataKeys`` to + return. The service may return fewer than this value. If + unspecified, at most 50 ``CmsMetadataKeys`` will be + returned. The maximum value is 1000; values greater than + 1000 will be coerced to 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListCmsMetadataKeys`` call. Provide this to retrieve the + subsequent page. + + When paginating, all other parameters provided to + ``ListCmsMetadataKeys`` must match the call that provided + the page token. + filter (str): + Optional. Expression to filter the response. + See syntax details at + https://developers.google.com/ad-manager/api/beta/filters + order_by (str): + Optional. Expression to specify sorting + order. See syntax details at + https://developers.google.com/ad-manager/api/beta/filters#order + skip (int): + Optional. Number of individual resources to + skip while paginating. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + skip: int = proto.Field( + proto.INT32, + number=6, + ) + + +class ListCmsMetadataKeysResponse(proto.Message): + r"""Response object for ``ListCmsMetadataKeysRequest`` containing + matching ``CmsMetadataKey`` objects. + + Attributes: + cms_metadata_keys (MutableSequence[google.ads.admanager_v1.types.CmsMetadataKey]): + The ``CmsMetadataKey`` objects from the specified network. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + total_size (int): + Total number of ``CmsMetadataKey`` objects. If a filter was + included in the request, this reflects the total number + after the filtering is applied. + + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response + field mask can be provided to the method by using the URL + parameter ``$fields`` or ``fields``, or by using the + HTTP/gRPC header ``X-Goog-FieldMask``. + + For more information, see + https://developers.google.com/ad-manager/api/beta/field-masks + """ + + @property + def raw_page(self): + return self + + cms_metadata_keys: MutableSequence[ + cms_metadata_key_messages.CmsMetadataKey + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=cms_metadata_key_messages.CmsMetadataKey, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/cms_metadata_value_enums.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/cms_metadata_value_enums.py new file mode 100644 index 000000000000..c8e57667f854 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/cms_metadata_value_enums.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 + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "CmsMetadataValueStatusEnum", + }, +) + + +class CmsMetadataValueStatusEnum(proto.Message): + r"""Wrapper message for + [CmsMetadataValueStatus][google.ads.admanager.v1.CmsMetadataValueStatusEnum.CmsMetadataValueStatus] + + """ + + class CmsMetadataValueStatus(proto.Enum): + r"""Status for CmsMetadataValue objects. + + Values: + CMS_METADATA_VALUE_STATUS_UNSPECIFIED (0): + Default value. This value is unused. + ACTIVE (1): + The value is active. + ARCHIVED (2): + The value is archived. + INACTIVE (3): + The value is not active. + """ + CMS_METADATA_VALUE_STATUS_UNSPECIFIED = 0 + ACTIVE = 1 + ARCHIVED = 2 + INACTIVE = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/cms_metadata_value_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/cms_metadata_value_messages.py new file mode 100644 index 000000000000..d8cfd693f15d --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/cms_metadata_value_messages.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 + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.ads.admanager_v1.types import cms_metadata_value_enums + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "CmsMetadataValue", + }, +) + + +class CmsMetadataValue(proto.Message): + r"""Key value pair associated with a piece of content from a + publisher's CMS. + + Attributes: + name (str): + Identifier. The resource name of the ``CmsMetadataValue``. + Format: + ``networks/{network_code}/cmsMetadataValues/{cms_metadata_value_id}`` + display_name (str): + The value of this key-value pair. + key (str): + Required. Immutable. The resource name of the + CmsMetadataKey. Format: + "networks/{network_code}/cmsMetadataKey/{cms_metadata_key_id}". + status (google.ads.admanager_v1.types.CmsMetadataValueStatusEnum.CmsMetadataValueStatus): + Output only. The status of this CMS metadata + value. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=3, + ) + key: str = proto.Field( + proto.STRING, + number=5, + ) + status: cms_metadata_value_enums.CmsMetadataValueStatusEnum.CmsMetadataValueStatus = proto.Field( + proto.ENUM, + number=6, + enum=cms_metadata_value_enums.CmsMetadataValueStatusEnum.CmsMetadataValueStatus, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/cms_metadata_value_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/cms_metadata_value_service.py new file mode 100644 index 000000000000..f56eed4c5958 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/cms_metadata_value_service.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +from google.ads.admanager_v1.types import cms_metadata_value_messages + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "GetCmsMetadataValueRequest", + "ListCmsMetadataValuesRequest", + "ListCmsMetadataValuesResponse", + }, +) + + +class GetCmsMetadataValueRequest(proto.Message): + r"""Request object for ``GetCmsMetadataValue`` method. + + Attributes: + name (str): + Required. The resource name of the CmsMetadataKey. Format: + ``networks/{network_code}/cmsMetadataValues/{cms_metadata_value_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListCmsMetadataValuesRequest(proto.Message): + r"""Request object for ``ListCmsMetadataValues`` method. + + Attributes: + parent (str): + Required. The parent, which owns this collection of + CmsMetadataValues. Format: ``networks/{network_code}`` + page_size (int): + Optional. The maximum number of ``CmsMetadataValues`` to + return. The service may return fewer than this value. If + unspecified, at most 50 ``CmsMetadataValues`` will be + returned. The maximum value is 1000; values greater than + 1000 will be coerced to 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListCmsMetadataValues`` call. Provide this to retrieve the + subsequent page. + + When paginating, all other parameters provided to + ``ListCmsMetadataValues`` must match the call that provided + the page token. + filter (str): + Optional. Expression to filter the response. + See syntax details at + https://developers.google.com/ad-manager/api/beta/filters + order_by (str): + Optional. Expression to specify sorting + order. See syntax details at + https://developers.google.com/ad-manager/api/beta/filters#order + skip (int): + Optional. Number of individual resources to + skip while paginating. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + skip: int = proto.Field( + proto.INT32, + number=6, + ) + + +class ListCmsMetadataValuesResponse(proto.Message): + r"""Response object for ``ListCmsMetadataValuesRequest`` containing + matching ``CmsMetadataValue`` objects. + + Attributes: + cms_metadata_values (MutableSequence[google.ads.admanager_v1.types.CmsMetadataValue]): + The ``CmsMetadataValue`` objects from the specified network. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + total_size (int): + Total number of ``CmsMetadataValue`` objects. If a filter + was included in the request, this reflects the total number + after the filtering is applied. + + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response + field mask can be provided to the method by using the URL + parameter ``$fields`` or ``fields``, or by using the + HTTP/gRPC header ``X-Goog-FieldMask``. + + For more information, see + https://developers.google.com/ad-manager/api/beta/field-masks + """ + + @property + def raw_page(self): + return self + + cms_metadata_values: MutableSequence[ + cms_metadata_value_messages.CmsMetadataValue + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=cms_metadata_value_messages.CmsMetadataValue, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/company_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/company_messages.py index 14755c8d80cf..5667fa5bf131 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/company_messages.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/company_messages.py @@ -41,41 +41,61 @@ class Company(proto.Message): ``networks/{network_code}/companies/{company_id}`` company_id (int): Output only. ``Company`` ID. + + This field is a member of `oneof`_ ``_company_id``. display_name (str): Required. The display name of the ``Company``. This value has a maximum length of 127 characters. + + This field is a member of `oneof`_ ``_display_name``. type_ (google.ads.admanager_v1.types.CompanyTypeEnum.CompanyType): Required. The type of the ``Company``. + + This field is a member of `oneof`_ ``_type``. address (str): Optional. The address for the ``Company``. This value has a maximum length of 1024 characters. + + This field is a member of `oneof`_ ``_address``. email (str): Optional. The email for the ``Company``. This value has a maximum length of 128 characters. + + This field is a member of `oneof`_ ``_email``. fax (str): Optional. The fax number for the ``Company``. This value has a maximum length of 63 characters. + + This field is a member of `oneof`_ ``_fax``. phone (str): Optional. The phone number for the ``Company``. This value has a maximum length of 63 characters. + + This field is a member of `oneof`_ ``_phone``. external_id (str): Optional. The external ID for the ``Company``. This value has a maximum length of 255 characters. + + This field is a member of `oneof`_ ``_external_id``. comment (str): Optional. Comments about the ``Company``. This value has a maximum length of 1024 characters. + + This field is a member of `oneof`_ ``_comment``. credit_status (google.ads.admanager_v1.types.CompanyCreditStatusEnum.CompanyCreditStatus): Optional. The credit status of the ``Company``. This attribute defaults to ``ACTIVE`` if basic settings are enabled and ``ON_HOLD`` if advance settings are enabled. + + This field is a member of `oneof`_ ``_credit_status``. applied_labels (MutableSequence[google.ads.admanager_v1.types.AppliedLabel]): Optional. The labels that are directly applied to the ``Company``. @@ -92,8 +112,12 @@ class Company(proto.Message): third_party_company_id (int): Optional. The ID of the Google-recognized canonicalized form of the ``Company``. + + This field is a member of `oneof`_ ``_third_party_company_id``. update_time (google.protobuf.timestamp_pb2.Timestamp): Output only. The time the ``Company`` was last modified. + + This field is a member of `oneof`_ ``_update_time``. """ name: str = proto.Field( @@ -103,44 +127,54 @@ class Company(proto.Message): company_id: int = proto.Field( proto.INT64, number=2, + optional=True, ) display_name: str = proto.Field( proto.STRING, number=3, + optional=True, ) type_: company_enums.CompanyTypeEnum.CompanyType = proto.Field( proto.ENUM, number=4, + optional=True, enum=company_enums.CompanyTypeEnum.CompanyType, ) address: str = proto.Field( proto.STRING, number=5, + optional=True, ) email: str = proto.Field( proto.STRING, number=6, + optional=True, ) fax: str = proto.Field( proto.STRING, number=7, + optional=True, ) phone: str = proto.Field( proto.STRING, number=8, + optional=True, ) external_id: str = proto.Field( proto.STRING, number=9, + optional=True, ) comment: str = proto.Field( proto.STRING, number=10, + optional=True, ) credit_status: company_enums.CompanyCreditStatusEnum.CompanyCreditStatus = ( proto.Field( proto.ENUM, number=11, + optional=True, enum=company_enums.CompanyCreditStatusEnum.CompanyCreditStatus, ) ) @@ -161,10 +195,12 @@ class Company(proto.Message): third_party_company_id: int = proto.Field( proto.INT64, number=16, + optional=True, ) update_time: timestamp_pb2.Timestamp = proto.Field( proto.MESSAGE, number=15, + optional=True, message=timestamp_pb2.Timestamp, ) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/company_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/company_service.py index c85ecafcc419..bd0c087b3b6c 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/company_service.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/company_service.py @@ -57,7 +57,7 @@ class ListCompaniesRequest(proto.Message): Optional. The maximum number of ``Companies`` to return. The service may return fewer than this value. If unspecified, at most 50 ``Companies`` will be returned. The maximum value is - 1000; values above 1000 will be coerced to 1000. + 1000; values greater than 1000 will be coerced to 1000. page_token (str): Optional. A page token, received from a previous ``ListCompanies`` call. Provide this to retrieve the @@ -121,8 +121,8 @@ class ListCompaniesResponse(proto.Message): included in the request, this reflects the total number after the filtering is applied. - ``total_size`` will not be calculated in the response unless - it has been included in a response field mask. The response + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response field mask can be provided to the method by using the URL parameter ``$fields`` or ``fields``, or by using the HTTP/gRPC header ``X-Goog-FieldMask``. diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/contact_enums.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/contact_enums.py new file mode 100644 index 000000000000..baca3c7df8d8 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/contact_enums.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 + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "ContactStatusEnum", + }, +) + + +class ContactStatusEnum(proto.Message): + r"""Wrapper message for + [ContactStatus][google.ads.admanager.v1.ContactStatusEnum.ContactStatus] + + """ + + class ContactStatus(proto.Enum): + r"""Describes the contact statuses. + + Values: + CONTACT_STATUS_UNSPECIFIED (0): + Default value. This value is unused. + INVITE_CANCELED (1): + The contact was invited to see their orders, + but the invitation was cancelled. + INVITE_EXPIRED (2): + The contact has been invited to see their + orders, but the invitation has already expired. + INVITE_PENDING (3): + The contact has been invited to see their + orders, but has not yet accepted the invitation. + UNINVITED (4): + The contact has not been invited to see their + orders. + USER_ACTIVE (5): + The contact has access to login and view + their orders. + USER_DISABLED (6): + The contact accepted an invitation to see + their orders, but their access was later + revoked. + """ + CONTACT_STATUS_UNSPECIFIED = 0 + INVITE_CANCELED = 1 + INVITE_EXPIRED = 2 + INVITE_PENDING = 3 + UNINVITED = 4 + USER_ACTIVE = 5 + USER_DISABLED = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/contact_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/contact_messages.py index 6349abb2d0cc..13bb31bd9451 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/contact_messages.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/contact_messages.py @@ -19,6 +19,8 @@ import proto # type: ignore +from google.ads.admanager_v1.types import contact_enums + __protobuf__ = proto.module( package="google.ads.admanager.v1", manifest={ @@ -40,19 +42,118 @@ class Contact(proto.Message): name (str): Identifier. The resource name of the ``Contact``. Format: ``networks/{network_code}/contacts/{contact_id}`` - company_display_name (str): - Output only. The display name of the Company. + display_name (str): + Required. The name of the contact. This + attribute has a maximum length of 127 + characters. + + This field is a member of `oneof`_ ``_display_name``. + company (str): + Required. Immutable. The resource name of the Company. + Format: "networks/{network_code}/companies/{company_id}". + + This field is a member of `oneof`_ ``_company``. + status (google.ads.admanager_v1.types.ContactStatusEnum.ContactStatus): + Output only. The status of the contact. This + attribute is assigned by Google. + + This field is a member of `oneof`_ ``_status``. + address (str): + Optional. The address of the contact. This + attribute has a maximum length of 1024 + characters. + + This field is a member of `oneof`_ ``_address``. + cell_phone (str): + Optional. The cell phone number where the + contact can be reached. + + This field is a member of `oneof`_ ``_cell_phone``. + comment (str): + Optional. A free-form text comment for the + contact. This attribute has a maximum length of + 1024 characters. + + This field is a member of `oneof`_ ``_comment``. + email (str): + Optional. The e-mail address where the + contact can be reached. This attribute has a + maximum length of 128 characters. + + This field is a member of `oneof`_ ``_email``. + fax (str): + Optional. The fax number where the contact + can be reached. This attribute has a maximum + length of 1024 characters. + + This field is a member of `oneof`_ ``_fax``. + title (str): + Optional. The job title of the contact. This + attribute has a maximum length of 1024 + characters. - This field is a member of `oneof`_ ``_company_display_name``. + This field is a member of `oneof`_ ``_title``. + work_phone (str): + Optional. The work phone number where the + contact can be reached. This attribute has a + maximum length of 1024 characters. + + This field is a member of `oneof`_ ``_work_phone``. """ name: str = proto.Field( proto.STRING, number=1, ) - company_display_name: str = proto.Field( + display_name: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + company: str = proto.Field( + proto.STRING, + number=5, + optional=True, + ) + status: contact_enums.ContactStatusEnum.ContactStatus = proto.Field( + proto.ENUM, + number=6, + optional=True, + enum=contact_enums.ContactStatusEnum.ContactStatus, + ) + address: str = proto.Field( + proto.STRING, + number=7, + optional=True, + ) + cell_phone: str = proto.Field( + proto.STRING, + number=8, + optional=True, + ) + comment: str = proto.Field( + proto.STRING, + number=9, + optional=True, + ) + email: str = proto.Field( + proto.STRING, + number=10, + optional=True, + ) + fax: str = proto.Field( + proto.STRING, + number=11, + optional=True, + ) + title: str = proto.Field( + proto.STRING, + number=12, + optional=True, + ) + work_phone: str = proto.Field( proto.STRING, - number=19, + number=13, optional=True, ) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/contact_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/contact_service.py new file mode 100644 index 000000000000..11a3f8f0de77 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/contact_service.py @@ -0,0 +1,285 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +from google.protobuf import field_mask_pb2 # type: ignore +import proto # type: ignore + +from google.ads.admanager_v1.types import contact_messages + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "GetContactRequest", + "ListContactsRequest", + "ListContactsResponse", + "CreateContactRequest", + "BatchCreateContactsRequest", + "BatchCreateContactsResponse", + "UpdateContactRequest", + "BatchUpdateContactsRequest", + "BatchUpdateContactsResponse", + }, +) + + +class GetContactRequest(proto.Message): + r"""Request object for ``GetContact`` method. + + Attributes: + name (str): + Required. The resource name of the Contact. Format: + ``networks/{network_code}/contacts/{contact_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListContactsRequest(proto.Message): + r"""Request object for ``ListContacts`` method. + + Attributes: + parent (str): + Required. The parent, which owns this collection of + Contacts. Format: ``networks/{network_code}`` + page_size (int): + Optional. The maximum number of ``Contacts`` to return. The + service may return fewer than this value. If unspecified, at + most 50 ``Contacts`` will be returned. The maximum value is + 1000; values greater than 1000 will be coerced to 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListContacts`` call. Provide this to retrieve the + subsequent page. + + When paginating, all other parameters provided to + ``ListContacts`` must match the call that provided the page + token. + filter (str): + Optional. Expression to filter the response. + See syntax details at + https://developers.google.com/ad-manager/api/beta/filters + order_by (str): + Optional. Expression to specify sorting + order. See syntax details at + https://developers.google.com/ad-manager/api/beta/filters#order + skip (int): + Optional. Number of individual resources to + skip while paginating. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + skip: int = proto.Field( + proto.INT32, + number=6, + ) + + +class ListContactsResponse(proto.Message): + r"""Response object for ``ListContactsRequest`` containing matching + ``Contact`` objects. + + Attributes: + contacts (MutableSequence[google.ads.admanager_v1.types.Contact]): + The ``Contact`` objects from the specified network. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + total_size (int): + Total number of ``Contact`` objects. If a filter was + included in the request, this reflects the total number + after the filtering is applied. + + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response + field mask can be provided to the method by using the URL + parameter ``$fields`` or ``fields``, or by using the + HTTP/gRPC header ``X-Goog-FieldMask``. + + For more information, see + https://developers.google.com/ad-manager/api/beta/field-masks + """ + + @property + def raw_page(self): + return self + + contacts: MutableSequence[contact_messages.Contact] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=contact_messages.Contact, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + + +class CreateContactRequest(proto.Message): + r"""Request object for ``CreateContact`` method. + + Attributes: + parent (str): + Required. The parent resource where this ``Contact`` will be + created. Format: ``networks/{network_code}`` + contact (google.ads.admanager_v1.types.Contact): + Required. The ``Contact`` to create. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + contact: contact_messages.Contact = proto.Field( + proto.MESSAGE, + number=2, + message=contact_messages.Contact, + ) + + +class BatchCreateContactsRequest(proto.Message): + r"""Request object for ``BatchCreateContacts`` method. + + Attributes: + parent (str): + Required. The parent resource where ``Contacts`` will be + created. Format: ``networks/{network_code}`` The parent + field in the CreateContactRequest must match this field. + requests (MutableSequence[google.ads.admanager_v1.types.CreateContactRequest]): + Required. The ``Contact`` objects to create. A maximum of + 100 objects can be created in a batch. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + requests: MutableSequence["CreateContactRequest"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="CreateContactRequest", + ) + + +class BatchCreateContactsResponse(proto.Message): + r"""Response object for ``BatchCreateContacts`` method. + + Attributes: + contacts (MutableSequence[google.ads.admanager_v1.types.Contact]): + The ``Contact`` objects created. + """ + + contacts: MutableSequence[contact_messages.Contact] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=contact_messages.Contact, + ) + + +class UpdateContactRequest(proto.Message): + r"""Request object for ``UpdateContact`` method. + + Attributes: + contact (google.ads.admanager_v1.types.Contact): + Required. The ``Contact`` to update. + + The ``Contact``'s ``name`` is used to identify the + ``Contact`` to update. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Required. The list of fields to update. + """ + + contact: contact_messages.Contact = proto.Field( + proto.MESSAGE, + number=1, + message=contact_messages.Contact, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class BatchUpdateContactsRequest(proto.Message): + r"""Request object for ``BatchUpdateContacts`` method. + + Attributes: + parent (str): + Required. The parent resource where ``Contacts`` will be + updated. Format: ``networks/{network_code}`` The parent + field in the UpdateContactRequest must match this field. + requests (MutableSequence[google.ads.admanager_v1.types.UpdateContactRequest]): + Required. The ``Contact`` objects to update. A maximum of + 100 objects can be updated in a batch. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + requests: MutableSequence["UpdateContactRequest"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="UpdateContactRequest", + ) + + +class BatchUpdateContactsResponse(proto.Message): + r"""Response object for ``BatchUpdateContacts`` method. + + Attributes: + contacts (MutableSequence[google.ads.admanager_v1.types.Contact]): + The ``Contact`` objects updated. + """ + + contacts: MutableSequence[contact_messages.Contact] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=contact_messages.Contact, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/content_bundle_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/content_bundle_messages.py new file mode 100644 index 000000000000..62f0a17006c1 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/content_bundle_messages.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 + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "ContentBundle", + }, +) + + +class ContentBundle(proto.Message): + r"""A [ContentBundle][google.ads.admanager.v1.ContentBundle] is a + grouping of individual [Content][google.ads.admanager.v1.Content]. A + [ContentBundle][google.ads.admanager.v1.ContentBundle] is defined as + including the [Content][google.ads.admanager.v1.Content] that match + certain filter rules along with the option to explicitly include or + exclude certain Content IDs. + + Attributes: + name (str): + Identifier. The resource name of the + [ContentBundle][google.ads.admanager.v1.ContentBundle]. + Format: + ``networks/{network_code}/contentBundles/{content_bundle_id}`` + display_name (str): + Required. The name of the + [ContentBundle][google.ads.admanager.v1.ContentBundle]. This + attribute is required and has a maximum length of 255 + characters. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/content_bundle_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/content_bundle_service.py new file mode 100644 index 000000000000..f97a13a50a3a --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/content_bundle_service.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +from google.ads.admanager_v1.types import content_bundle_messages + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "GetContentBundleRequest", + "ListContentBundlesRequest", + "ListContentBundlesResponse", + }, +) + + +class GetContentBundleRequest(proto.Message): + r"""Request object for ``GetContentBundle`` method. + + Attributes: + name (str): + Required. The resource name of the ContentBundle. Format: + ``networks/{network_code}/contentBundles/{content_bundle_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListContentBundlesRequest(proto.Message): + r"""Request object for ``ListContentBundles`` method. + + Attributes: + parent (str): + Required. The parent, which owns this collection of + ContentBundles. Format: ``networks/{network_code}`` + page_size (int): + Optional. The maximum number of ``ContentBundles`` to + return. The service may return fewer than this value. If + unspecified, at most 50 ``ContentBundles`` will be returned. + The maximum value is 1000; values greater than 1000 will be + coerced to 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListContentBundles`` call. Provide this to retrieve the + subsequent page. + + When paginating, all other parameters provided to + ``ListContentBundles`` must match the call that provided the + page token. + filter (str): + Optional. Expression to filter the response. + See syntax details at + https://developers.google.com/ad-manager/api/beta/filters + order_by (str): + Optional. Expression to specify sorting + order. See syntax details at + https://developers.google.com/ad-manager/api/beta/filters#order + skip (int): + Optional. Number of individual resources to + skip while paginating. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + skip: int = proto.Field( + proto.INT32, + number=6, + ) + + +class ListContentBundlesResponse(proto.Message): + r"""Response object for ``ListContentBundlesRequest`` containing + matching ``ContentBundle`` objects. + + Attributes: + content_bundles (MutableSequence[google.ads.admanager_v1.types.ContentBundle]): + The ``ContentBundle`` objects from the specified network. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + total_size (int): + Total number of ``ContentBundle`` objects. If a filter was + included in the request, this reflects the total number + after the filtering is applied. + + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response + field mask can be provided to the method by using the URL + parameter ``$fields`` or ``fields``, or by using the + HTTP/gRPC header ``X-Goog-FieldMask``. + + For more information, see + https://developers.google.com/ad-manager/api/beta/field-masks + """ + + @property + def raw_page(self): + return self + + content_bundles: MutableSequence[ + content_bundle_messages.ContentBundle + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=content_bundle_messages.ContentBundle, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/content_label_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/content_label_messages.py new file mode 100644 index 000000000000..a111ac04a154 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/content_label_messages.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "ContentLabel", + }, +) + + +class ContentLabel(proto.Message): + r"""A content label. + + Attributes: + name (str): + Identifier. The resource name of the ``ContentLabel``. + Format: + ``networks/{network_code}/contentLabels/{content_label_id}`` + display_name (str): + Optional. The display name of the ``ContentLabel``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/content_label_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/content_label_service.py new file mode 100644 index 000000000000..c70c118f105e --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/content_label_service.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +from google.ads.admanager_v1.types import content_label_messages + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "GetContentLabelRequest", + "ListContentLabelsRequest", + "ListContentLabelsResponse", + }, +) + + +class GetContentLabelRequest(proto.Message): + r"""Request object for ``GetContentLabel`` method. + + Attributes: + name (str): + Required. The resource name of the ContentLabel. Format: + ``networks/{network_code}/contentLabels/{content_label_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListContentLabelsRequest(proto.Message): + r"""Request object for ``ListContentLabels`` method. + + Attributes: + parent (str): + Required. The parent, which owns this collection of + ContentLabels. Format: ``networks/{network_code}`` + page_size (int): + Optional. The maximum number of ``ContentLabels`` to return. + The service may return fewer than this value. If + unspecified, at most 50 ``ContentLabels`` will be returned. + The maximum value is 1000; values greater than 1000 will be + coerced to 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListContentLabels`` call. Provide this to retrieve the + subsequent page. + + When paginating, all other parameters provided to + ``ListContentLabels`` must match the call that provided the + page token. + filter (str): + Optional. Expression to filter the response. + See syntax details at + https://developers.google.com/ad-manager/api/beta/filters + order_by (str): + Optional. Expression to specify sorting + order. See syntax details at + https://developers.google.com/ad-manager/api/beta/filters#order + skip (int): + Optional. Number of individual resources to + skip while paginating. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + skip: int = proto.Field( + proto.INT32, + number=6, + ) + + +class ListContentLabelsResponse(proto.Message): + r"""Response object for ``ListContentLabelsRequest`` containing matching + ``ContentLabel`` objects. + + Attributes: + content_labels (MutableSequence[google.ads.admanager_v1.types.ContentLabel]): + The ``ContentLabel`` objects from the specified network. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + total_size (int): + Total number of ``ContentLabel`` objects. If a filter was + included in the request, this reflects the total number + after the filtering is applied. + + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response + field mask can be provided to the method by using the URL + parameter ``$fields`` or ``fields``, or by using the + HTTP/gRPC header ``X-Goog-FieldMask``. + + For more information, see + https://developers.google.com/ad-manager/api/beta/field-masks + """ + + @property + def raw_page(self): + return self + + content_labels: MutableSequence[ + content_label_messages.ContentLabel + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=content_label_messages.ContentLabel, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/content_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/content_messages.py new file mode 100644 index 000000000000..10dca57c5d55 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/content_messages.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 + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "Content", + }, +) + + +class Content(proto.Message): + r"""A piece of content from a Publisher's CMS. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + Identifier. The resource name of the ``Content``. Format: + ``networks/{network_code}/content/{content_id}`` + display_name (str): + Output only. The name of the ``Content``. + + This field is a member of `oneof`_ ``_display_name``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/content_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/content_service.py new file mode 100644 index 000000000000..883f383dccfc --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/content_service.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +from google.ads.admanager_v1.types import content_messages + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "GetContentRequest", + "ListContentRequest", + "ListContentResponse", + }, +) + + +class GetContentRequest(proto.Message): + r"""Request object for ``GetContent`` method. + + Attributes: + name (str): + Required. The resource name of the Content. Format: + ``networks/{network_code}/content/{content_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListContentRequest(proto.Message): + r"""Request object for ``ListContent`` method. + + Attributes: + parent (str): + Required. The parent, which owns this collection of Content. + Format: ``networks/{network_code}`` + page_size (int): + Optional. The maximum number of ``Content`` to return. The + service may return fewer than this value. If unspecified, at + most 50 ``Content`` will be returned. The maximum value is + 1000; values greater than 1000 will be coerced to 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListContent`` call. Provide this to retrieve the + subsequent page. + + When paginating, all other parameters provided to + ``ListContent`` must match the call that provided the page + token. + filter (str): + Optional. Expression to filter the response. + See syntax details at + https://developers.google.com/ad-manager/api/beta/filters + order_by (str): + Optional. Expression to specify sorting + order. See syntax details at + https://developers.google.com/ad-manager/api/beta/filters#order + skip (int): + Optional. Number of individual resources to + skip while paginating. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + skip: int = proto.Field( + proto.INT32, + number=6, + ) + + +class ListContentResponse(proto.Message): + r"""Response object for ``ListContentRequest`` containing matching + ``Content`` objects. + + Attributes: + content (MutableSequence[google.ads.admanager_v1.types.Content]): + The ``Content`` objects from the specified network. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + total_size (int): + Total number of ``Content`` objects. If a filter was + included in the request, this reflects the total number + after the filtering is applied. + + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response + field mask can be provided to the method by using the URL + parameter ``$fields`` or ``fields``, or by using the + HTTP/gRPC header ``X-Goog-FieldMask``. + + For more information, see + https://developers.google.com/ad-manager/api/beta/field-masks + """ + + @property + def raw_page(self): + return self + + content: MutableSequence[content_messages.Content] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=content_messages.Content, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/creative_template_enums.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/creative_template_enums.py new file mode 100644 index 000000000000..11eec0934cb7 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/creative_template_enums.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 + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "CreativeTemplateTypeEnum", + "CreativeTemplateStatusEnum", + }, +) + + +class CreativeTemplateTypeEnum(proto.Message): + r"""Wrapper message for + [CreativeTemplateType][google.ads.admanager.v1.CreativeTemplateTypeEnum.CreativeTemplateType] + + """ + + class CreativeTemplateType(proto.Enum): + r"""Describes type of the creative template. + + Values: + CREATIVE_TEMPLATE_TYPE_UNSPECIFIED (0): + Default value. This value is unused. + STANDARD (1): + Creative templates that are included in Ad + Manager by default. + CUSTOM (2): + Creative templates created by an + administrator or other user in the network. + """ + CREATIVE_TEMPLATE_TYPE_UNSPECIFIED = 0 + STANDARD = 1 + CUSTOM = 2 + + +class CreativeTemplateStatusEnum(proto.Message): + r"""Wrapper message for + [CreativeTemplateStatus][google.ads.admanager.v1.CreativeTemplateStatusEnum.CreativeTemplateStatus] + + """ + + class CreativeTemplateStatus(proto.Enum): + r"""Describes status of the creative template + + Values: + CREATIVE_TEMPLATE_STATUS_UNSPECIFIED (0): + Default value. This value is unused. + ACTIVE (1): + The CreativeTemplate is active + DELETED (2): + The CreativeTemplate is deleted. Creatives + created from this CreativeTemplate can no longer + serve. + INACTIVE (3): + The CreativeTemplate is inactive. Users + cannot create new creatives from this template, + but existing ones can be edited and continue to + serve + """ + CREATIVE_TEMPLATE_STATUS_UNSPECIFIED = 0 + ACTIVE = 1 + DELETED = 2 + INACTIVE = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/creative_template_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/creative_template_messages.py new file mode 100644 index 000000000000..e0fa7533f5a3 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/creative_template_messages.py @@ -0,0 +1,520 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +from google.ads.admanager_v1.types import ( + creative_template_enums, + creative_template_variable_url_type_enum, +) + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "CreativeTemplate", + "CreativeTemplateVariable", + }, +) + + +class CreativeTemplate(proto.Message): + r"""A template that can be used to create a [TemplateCreative][]. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + Identifier. The resource name of the creative template. + Format: + ``networks/{network_code}/creativeTemplates/{creative_template_id}`` + display_name (str): + Required. The display name of the creative + template. This has a maximum length of 255 + characters. + + This field is a member of `oneof`_ ``_display_name``. + description (str): + Optional. The description of the creative + template. + + This field is a member of `oneof`_ ``_description``. + snippet (str): + Required. The code snippet of the creative + template, with placeholders for the associated + variables. + + This field is a member of `oneof`_ ``_snippet``. + status (google.ads.admanager_v1.types.CreativeTemplateStatusEnum.CreativeTemplateStatus): + Output only. The status of the creative + template. This attribute is assigned by Google. + + This field is a member of `oneof`_ ``_status``. + type_ (google.ads.admanager_v1.types.CreativeTemplateTypeEnum.CreativeTemplateType): + Optional. The type of the creative template. Users can only + create or update ``CreativeTemplateType.CUSTOM`` templates. + + This field is a member of `oneof`_ ``_type``. + interstitial (bool): + Optional. ``True`` if this creative template produces + out-of-page creatives. Creative templates with this setting + enabled must include the viewed impression macro. + + This field is a member of `oneof`_ ``_interstitial``. + native_eligible (bool): + Optional. ``True`` if this creative template produces + native-eligible creatives. + + This field is a member of `oneof`_ ``_native_eligible``. + native_video_eligible (bool): + Optional. ``True`` if this creative template produces native + video-eligible creatives. + + This field is a member of `oneof`_ ``_native_video_eligible``. + safe_frame_compatible (bool): + Optional. Whether the Creative produced is compatible for + SafeFrame rendering. This attribute defaults to ``True``. + + This field is a member of `oneof`_ ``_safe_frame_compatible``. + variables (MutableSequence[google.ads.admanager_v1.types.CreativeTemplateVariable]): + Required. The list of creative template + variables. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + description: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + snippet: str = proto.Field( + proto.STRING, + number=4, + optional=True, + ) + status: creative_template_enums.CreativeTemplateStatusEnum.CreativeTemplateStatus = proto.Field( + proto.ENUM, + number=6, + optional=True, + enum=creative_template_enums.CreativeTemplateStatusEnum.CreativeTemplateStatus, + ) + type_: creative_template_enums.CreativeTemplateTypeEnum.CreativeTemplateType = ( + proto.Field( + proto.ENUM, + number=7, + optional=True, + enum=creative_template_enums.CreativeTemplateTypeEnum.CreativeTemplateType, + ) + ) + interstitial: bool = proto.Field( + proto.BOOL, + number=8, + optional=True, + ) + native_eligible: bool = proto.Field( + proto.BOOL, + number=9, + optional=True, + ) + native_video_eligible: bool = proto.Field( + proto.BOOL, + number=10, + optional=True, + ) + safe_frame_compatible: bool = proto.Field( + proto.BOOL, + number=12, + optional=True, + ) + variables: MutableSequence["CreativeTemplateVariable"] = proto.RepeatedField( + proto.MESSAGE, + number=14, + message="CreativeTemplateVariable", + ) + + +class CreativeTemplateVariable(proto.Message): + r"""Represents a variable defined in a creative template. + + 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: + asset_variable (google.ads.admanager_v1.types.CreativeTemplateVariable.AssetCreativeTemplateVariable): + Optional. Represents a file asset variable + defined in a creative template. + + This field is a member of `oneof`_ ``SubType``. + list_string_variable (google.ads.admanager_v1.types.CreativeTemplateVariable.ListStringCreativeTemplateVariable): + Optional. Represents a list variable defined + in a creative template. + + This field is a member of `oneof`_ ``SubType``. + long_variable (google.ads.admanager_v1.types.CreativeTemplateVariable.LongCreativeTemplateVariable): + Optional. Represents a long variable defined + in a creative template. + + This field is a member of `oneof`_ ``SubType``. + string_variable (google.ads.admanager_v1.types.CreativeTemplateVariable.StringCreativeTemplateVariable): + Optional. Represents a string variable + defined in a creative template. + + This field is a member of `oneof`_ ``SubType``. + url_variable (google.ads.admanager_v1.types.CreativeTemplateVariable.UrlCreativeTemplateVariable): + Optional. Represents a url variable defined + in a creative template. + + This field is a member of `oneof`_ ``SubType``. + label (str): + Required. Label that is displayed to users + when creating from the creative template. This + has a maximum length of 127 characters. + + This field is a member of `oneof`_ ``_label``. + unique_display_name (str): + Output only. Unique name used to identify the + variable. This attribute is assigned by Google + when a creative template variable is created. + + This field is a member of `oneof`_ ``_unique_display_name``. + description (str): + Required. A descriptive help text that is + displayed to users along with the label. This + attribute has a maximum length of 255 + characters. + + This field is a member of `oneof`_ ``_description``. + required (bool): + Optional. ``True`` if this variable is required to be filled + in by users when creating a creative from the creative + template. + + This field is a member of `oneof`_ ``_required``. + """ + + class AssetCreativeTemplateVariable(proto.Message): + r"""Represents a file asset variable defined in a creative template. + + Use [AssetCreativeTemplateVariableValue][] to specify the value for + this variable when creating a [TemplateCreative][] from a + [CreativeTemplate][google.ads.admanager.v1.CreativeTemplate]. + + Attributes: + mime_types (MutableSequence[google.ads.admanager_v1.types.CreativeTemplateVariable.AssetCreativeTemplateVariable.MimeType]): + Optional. The set of allowed MIME types. If + unspecified, all MIME types are allowed. + """ + + class MimeType(proto.Enum): + r"""Different MIME types that the asset variable supports. + + Values: + MIME_TYPE_UNSPECIFIED (0): + Default value. This value is unused. + JPG (1): + The ``image/jpeg`` MIME type. + PNG (2): + The ``image/png`` MIME type. + GIF (3): + The ``image/gif`` MIME type. + """ + MIME_TYPE_UNSPECIFIED = 0 + JPG = 1 + PNG = 2 + GIF = 3 + + mime_types: MutableSequence[ + "CreativeTemplateVariable.AssetCreativeTemplateVariable.MimeType" + ] = proto.RepeatedField( + proto.ENUM, + number=1, + enum="CreativeTemplateVariable.AssetCreativeTemplateVariable.MimeType", + ) + + class ListStringCreativeTemplateVariable(proto.Message): + r"""Represents a list variable defined in a creative template. This is + similar to + [StringCreativeTemplateVariable][google.ads.admanager.v1.CreativeTemplateVariable.StringCreativeTemplateVariable], + except that there are possible choices to choose from. + + Use [StringCreativeTemplateVariableValue][] to specify the value for + this variable when creating a [TemplateCreative][] from a + [CreativeTemplate][google.ads.admanager.v1.CreativeTemplate]. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + default_value (str): + Optional. Default value to be filled in when + creating creatives from the creative template. + + This field is a member of `oneof`_ ``_default_value``. + sample_value (str): + Optional. Sample value that is used when + previewing the template in the UI. + + This field is a member of `oneof`_ ``_sample_value``. + choices (MutableSequence[google.ads.admanager_v1.types.CreativeTemplateVariable.ListStringCreativeTemplateVariable.VariableChoice]): + Optional. The selectable values that the user + can choose from. + allow_other_choice (bool): + Optional. ``True`` if a user can specify an 'other' value. + For example, if a variable called backgroundColor is defined + as a list with values: red, green, blue, this boolean can be + set to allow a user to enter a value not on the list such as + purple. + + This field is a member of `oneof`_ ``_allow_other_choice``. + """ + + class VariableChoice(proto.Message): + r"""Stores variable choices selectable by users. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + label (str): + Required. A label is displayed to users when creating a + [TemplateCreative][]. This attribute is intended to be more + descriptive than value. This attribute has a maximum length + of 255 characters. + + This field is a member of `oneof`_ ``_label``. + value (str): + Required. When creating a [TemplateCreative][], the value in + [StringCreativeTemplateVariableValue][] should match this + value, if you intend to select this value. This attribute + has a maximum length of 255 characters. + + This field is a member of `oneof`_ ``_value``. + """ + + label: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + value: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + + default_value: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + sample_value: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + choices: MutableSequence[ + "CreativeTemplateVariable.ListStringCreativeTemplateVariable.VariableChoice" + ] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message="CreativeTemplateVariable.ListStringCreativeTemplateVariable.VariableChoice", + ) + allow_other_choice: bool = proto.Field( + proto.BOOL, + number=4, + optional=True, + ) + + class LongCreativeTemplateVariable(proto.Message): + r"""Represents a long variable defined in a creative template. + + Use [LongCreativeTemplateVariableValue][] to specify the value for + this variable when creating [TemplateCreative][] from a + [CreativeTemplate][google.ads.admanager.v1.CreativeTemplate]. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + default_value (int): + Optional. Default value to be filled in when + creating creatives from the creative template. + + This field is a member of `oneof`_ ``_default_value``. + sample_value (int): + Optional. Sample value that is used when + previewing the template in the UI. + + This field is a member of `oneof`_ ``_sample_value``. + """ + + default_value: int = proto.Field( + proto.INT64, + number=1, + optional=True, + ) + sample_value: int = proto.Field( + proto.INT64, + number=2, + optional=True, + ) + + class StringCreativeTemplateVariable(proto.Message): + r"""Represents a string variable defined in a creative template. + + Use [StringCreativeTemplateVariableValue][] to specify the value for + this variable when creating [TemplateCreative][] from a + [CreativeTemplate][google.ads.admanager.v1.CreativeTemplate]. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + default_value (str): + Optional. Default value to be filled in when + creating creatives from the creative template. + + This field is a member of `oneof`_ ``_default_value``. + sample_value (str): + Optional. Sample value that is used when + previewing the template in the UI. + + This field is a member of `oneof`_ ``_sample_value``. + """ + + default_value: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + sample_value: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + + class UrlCreativeTemplateVariable(proto.Message): + r"""Represents a url variable defined in a creative template. + + Use [UrlCreativeTemplateVariableValue][] to specify the value for + this variable when creating a [TemplateCreative][] from a + [CreativeTemplate][google.ads.admanager.v1.CreativeTemplate]. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + default_value (str): + Optional. Default value to be filled in when + creating creatives from the creative template. + + This field is a member of `oneof`_ ``_default_value``. + sample_value (str): + Optional. Sample value that is used when + previewing the template in the UI. + + This field is a member of `oneof`_ ``_sample_value``. + url_type (google.ads.admanager_v1.types.CreativeTemplateVariableUrlTypeEnum.CreativeTemplateVariableUrlType): + Optional. The type of URL that this variable + represents. Different types of URLs may be + handled differently at rendering time. + + This field is a member of `oneof`_ ``_url_type``. + """ + + default_value: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + sample_value: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + url_type: creative_template_variable_url_type_enum.CreativeTemplateVariableUrlTypeEnum.CreativeTemplateVariableUrlType = proto.Field( + proto.ENUM, + number=4, + optional=True, + enum=creative_template_variable_url_type_enum.CreativeTemplateVariableUrlTypeEnum.CreativeTemplateVariableUrlType, + ) + + asset_variable: AssetCreativeTemplateVariable = proto.Field( + proto.MESSAGE, + number=5, + oneof="SubType", + message=AssetCreativeTemplateVariable, + ) + list_string_variable: ListStringCreativeTemplateVariable = proto.Field( + proto.MESSAGE, + number=7, + oneof="SubType", + message=ListStringCreativeTemplateVariable, + ) + long_variable: LongCreativeTemplateVariable = proto.Field( + proto.MESSAGE, + number=8, + oneof="SubType", + message=LongCreativeTemplateVariable, + ) + string_variable: StringCreativeTemplateVariable = proto.Field( + proto.MESSAGE, + number=9, + oneof="SubType", + message=StringCreativeTemplateVariable, + ) + url_variable: UrlCreativeTemplateVariable = proto.Field( + proto.MESSAGE, + number=10, + oneof="SubType", + message=UrlCreativeTemplateVariable, + ) + label: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + unique_display_name: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + description: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + required: bool = proto.Field( + proto.BOOL, + number=4, + optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/creative_template_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/creative_template_service.py new file mode 100644 index 000000000000..7247e40fc9c0 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/creative_template_service.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +from google.ads.admanager_v1.types import creative_template_messages + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "GetCreativeTemplateRequest", + "ListCreativeTemplatesRequest", + "ListCreativeTemplatesResponse", + }, +) + + +class GetCreativeTemplateRequest(proto.Message): + r"""Request object for ``GetCreativeTemplate`` method. + + Attributes: + name (str): + Required. The resource name of the CreativeTemplate. Format: + ``networks/{network_code}/creativeTemplates/{creative_template_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListCreativeTemplatesRequest(proto.Message): + r"""Request object for ``ListCreativeTemplates`` method. + + Attributes: + parent (str): + Required. The parent, which owns this collection of + CreativeTemplates. Format: ``networks/{network_code}`` + page_size (int): + Optional. The maximum number of ``CreativeTemplates`` to + return. The service may return fewer than this value. If + unspecified, at most 50 ``CreativeTemplates`` will be + returned. The maximum value is 1000; values greater than + 1000 will be coerced to 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListCreativeTemplates`` call. Provide this to retrieve the + subsequent page. + + When paginating, all other parameters provided to + ``ListCreativeTemplates`` must match the call that provided + the page token. + filter (str): + Optional. Expression to filter the response. + See syntax details at + https://developers.google.com/ad-manager/api/beta/filters + order_by (str): + Optional. Expression to specify sorting + order. See syntax details at + https://developers.google.com/ad-manager/api/beta/filters#order + skip (int): + Optional. Number of individual resources to + skip while paginating. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + skip: int = proto.Field( + proto.INT32, + number=6, + ) + + +class ListCreativeTemplatesResponse(proto.Message): + r"""Response object for ``ListCreativeTemplatesRequest`` containing + matching ``CreativeTemplate`` objects. + + Attributes: + creative_templates (MutableSequence[google.ads.admanager_v1.types.CreativeTemplate]): + The ``CreativeTemplate`` objects from the specified network. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + total_size (int): + Total number of ``CreativeTemplate`` objects. If a filter + was included in the request, this reflects the total number + after the filtering is applied. + + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response + field mask can be provided to the method by using the URL + parameter ``$fields`` or ``fields``, or by using the + HTTP/gRPC header ``X-Goog-FieldMask``. + + For more information, see + https://developers.google.com/ad-manager/api/beta/field-masks + """ + + @property + def raw_page(self): + return self + + creative_templates: MutableSequence[ + creative_template_messages.CreativeTemplate + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=creative_template_messages.CreativeTemplate, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/creative_template_variable_url_type_enum.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/creative_template_variable_url_type_enum.py new file mode 100644 index 000000000000..5f4e2f19313a --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/creative_template_variable_url_type_enum.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 + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "CreativeTemplateVariableUrlTypeEnum", + }, +) + + +class CreativeTemplateVariableUrlTypeEnum(proto.Message): + r"""Wrapper message for + [CreativeTemplateVariableUrlType][google.ads.admanager.v1.CreativeTemplateVariableUrlTypeEnum.CreativeTemplateVariableUrlType] + + """ + + class CreativeTemplateVariableUrlType(proto.Enum): + r"""Types of URLs that a UrlCreativeTemplateVariable can + represent. + + Values: + CREATIVE_TEMPLATE_VARIABLE_URL_TYPE_UNSPECIFIED (0): + Default value. This value is unused. + CLICK_TRACKER (1): + Click tracking URL. + DEEPLINK (2): + Deep-link URL. + IMPRESSION_TRACKER (3): + Impression tracking URL. + STANDARD_HTTP (4): + Standard HTTP URL. + """ + CREATIVE_TEMPLATE_VARIABLE_URL_TYPE_UNSPECIFIED = 0 + CLICK_TRACKER = 1 + DEEPLINK = 2 + IMPRESSION_TRACKER = 3 + STANDARD_HTTP = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_field_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_field_messages.py index a98f774675b8..263c5e3ce039 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_field_messages.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_field_messages.py @@ -140,7 +140,7 @@ class CustomFieldOption(proto.Message): Attributes: custom_field_option_id (int): - Output only. ``CustomFieldOption`` ID. + Optional. Non-empty default. ``CustomFieldOption`` ID. display_name (str): Required. The display name of the ``CustomFieldOption``. diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_field_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_field_service.py index ac419f69d893..1dfeeced9652 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_field_service.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_field_service.py @@ -17,6 +17,7 @@ from typing import MutableMapping, MutableSequence +from google.protobuf import field_mask_pb2 # type: ignore import proto # type: ignore from google.ads.admanager_v1.types import custom_field_messages @@ -27,6 +28,16 @@ "GetCustomFieldRequest", "ListCustomFieldsRequest", "ListCustomFieldsResponse", + "CreateCustomFieldRequest", + "BatchCreateCustomFieldsRequest", + "BatchCreateCustomFieldsResponse", + "UpdateCustomFieldRequest", + "BatchUpdateCustomFieldsRequest", + "BatchUpdateCustomFieldsResponse", + "BatchActivateCustomFieldsRequest", + "BatchActivateCustomFieldsResponse", + "BatchDeactivateCustomFieldsRequest", + "BatchDeactivateCustomFieldsResponse", }, ) @@ -57,8 +68,8 @@ class ListCustomFieldsRequest(proto.Message): Optional. The maximum number of ``CustomFields`` to return. The service may return fewer than this value. If unspecified, at most 50 ``CustomFields`` will be returned. - The maximum value is 1000; values above 1000 will be coerced - to 1000. + The maximum value is 1000; values greater than 1000 will be + coerced to 1000. page_token (str): Optional. A page token, received from a previous ``ListCustomFields`` call. Provide this to retrieve the @@ -122,8 +133,8 @@ class ListCustomFieldsResponse(proto.Message): included in the request, this reflects the total number after the filtering is applied. - ``total_size`` will not be calculated in the response unless - it has been included in a response field mask. The response + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response field mask can be provided to the method by using the URL parameter ``$fields`` or ``fields``, or by using the HTTP/gRPC header ``X-Goog-FieldMask``. @@ -153,4 +164,185 @@ def raw_page(self): ) +class CreateCustomFieldRequest(proto.Message): + r"""Request object for ``CreateCustomField`` method. + + Attributes: + parent (str): + Required. The parent resource where this ``CustomField`` + will be created. Format: ``networks/{network_code}`` + custom_field (google.ads.admanager_v1.types.CustomField): + Required. The ``CustomField`` to create. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + custom_field: custom_field_messages.CustomField = proto.Field( + proto.MESSAGE, + number=2, + message=custom_field_messages.CustomField, + ) + + +class BatchCreateCustomFieldsRequest(proto.Message): + r"""Request object for ``BatchCreateCustomFields`` method. + + Attributes: + parent (str): + Required. The parent resource where ``CustomFields`` will be + created. Format: ``networks/{network_code}`` The parent + field in the CreateCustomFieldRequest must match this field. + requests (MutableSequence[google.ads.admanager_v1.types.CreateCustomFieldRequest]): + Required. The ``CustomField`` objects to create. A maximum + of 100 objects can be created in a batch. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + requests: MutableSequence["CreateCustomFieldRequest"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="CreateCustomFieldRequest", + ) + + +class BatchCreateCustomFieldsResponse(proto.Message): + r"""Response object for ``BatchCreateCustomFields`` method. + + Attributes: + custom_fields (MutableSequence[google.ads.admanager_v1.types.CustomField]): + The ``CustomField`` objects created. + """ + + custom_fields: MutableSequence[ + custom_field_messages.CustomField + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=custom_field_messages.CustomField, + ) + + +class UpdateCustomFieldRequest(proto.Message): + r"""Request object for ``UpdateCustomField`` method. + + Attributes: + custom_field (google.ads.admanager_v1.types.CustomField): + Required. The ``CustomField`` to update. + + The ``CustomField``'s ``name`` is used to identify the + ``CustomField`` to update. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Required. The list of fields to update. + """ + + custom_field: custom_field_messages.CustomField = proto.Field( + proto.MESSAGE, + number=1, + message=custom_field_messages.CustomField, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class BatchUpdateCustomFieldsRequest(proto.Message): + r"""Request object for ``BatchUpdateCustomFields`` method. + + Attributes: + parent (str): + Required. The parent resource where ``CustomFields`` will be + updated. Format: ``networks/{network_code}`` The parent + field in the UpdateCustomFieldRequest must match this field. + requests (MutableSequence[google.ads.admanager_v1.types.UpdateCustomFieldRequest]): + Required. The ``CustomField`` objects to update. A maximum + of 100 objects can be updated in a batch. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + requests: MutableSequence["UpdateCustomFieldRequest"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="UpdateCustomFieldRequest", + ) + + +class BatchUpdateCustomFieldsResponse(proto.Message): + r"""Response object for ``BatchUpdateCustomFields`` method. + + Attributes: + custom_fields (MutableSequence[google.ads.admanager_v1.types.CustomField]): + The ``CustomField`` objects updated. + """ + + custom_fields: MutableSequence[ + custom_field_messages.CustomField + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=custom_field_messages.CustomField, + ) + + +class BatchActivateCustomFieldsRequest(proto.Message): + r"""Request message for ``BatchActivateCustomFields`` method. + + Attributes: + parent (str): + Required. Format: ``networks/{network_code}`` + names (MutableSequence[str]): + Required. The resource names of the ``CustomField`` objects + to activate. Format: + ``networks/{network_code}/customFields/{custom_field_id}`` + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + +class BatchActivateCustomFieldsResponse(proto.Message): + r"""Response object for ``BatchActivateCustomFields`` method.""" + + +class BatchDeactivateCustomFieldsRequest(proto.Message): + r"""Request message for ``BatchDeactivateCustomFields`` method. + + Attributes: + parent (str): + Required. Format: ``networks/{network_code}`` + names (MutableSequence[str]): + Required. The resource names of the ``CustomField`` objects + to deactivate. Format: + ``networks/{network_code}/customFields/{custom_field_id}`` + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + +class BatchDeactivateCustomFieldsResponse(proto.Message): + r"""Response object for ``BatchDeactivateCustomFields`` method.""" + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_targeting_key_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_targeting_key_messages.py index ac562ba688ea..00cee67d9383 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_targeting_key_messages.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_targeting_key_messages.py @@ -32,6 +32,8 @@ class CustomTargetingKey(proto.Message): r"""The ``CustomTargetingKey`` resource. + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: name (str): Identifier. The resource name of the ``CustomTargetingKey``. @@ -39,22 +41,34 @@ class CustomTargetingKey(proto.Message): ``networks/{network_code}/customTargetingKeys/{custom_targeting_key_id}`` custom_targeting_key_id (int): Output only. ``CustomTargetingKey`` ID. + + This field is a member of `oneof`_ ``_custom_targeting_key_id``. ad_tag_name (str): Immutable. Name of the key. Keys can contain up to 10 characters each. You can use alphanumeric characters and symbols other than the following: ", ', =, !, +, #, \*, ~, ;, ^, (, ), <, >, [, ], the white space character. + + This field is a member of `oneof`_ ``_ad_tag_name``. display_name (str): Optional. Descriptive name for the ``CustomTargetingKey``. + + This field is a member of `oneof`_ ``_display_name``. type_ (google.ads.admanager_v1.types.CustomTargetingKeyTypeEnum.CustomTargetingKeyType): Required. Indicates whether users will select from predefined values or create new targeting values, while specifying targeting criteria for a line item. + + This field is a member of `oneof`_ ``_type``. status (google.ads.admanager_v1.types.CustomTargetingKeyStatusEnum.CustomTargetingKeyStatus): Output only. Status of the ``CustomTargetingKey``. + + This field is a member of `oneof`_ ``_status``. reportable_type (google.ads.admanager_v1.types.CustomTargetingKeyReportableTypeEnum.CustomTargetingKeyReportableType): Required. Reportable state of the ``CustomTargetingKey``. + + This field is a member of `oneof`_ ``_reportable_type``. """ name: str = proto.Field( @@ -64,28 +78,34 @@ class CustomTargetingKey(proto.Message): custom_targeting_key_id: int = proto.Field( proto.INT64, number=2, + optional=True, ) ad_tag_name: str = proto.Field( proto.STRING, number=3, + optional=True, ) display_name: str = proto.Field( proto.STRING, number=4, + optional=True, ) type_: custom_targeting_key_enums.CustomTargetingKeyTypeEnum.CustomTargetingKeyType = proto.Field( proto.ENUM, number=5, + optional=True, enum=custom_targeting_key_enums.CustomTargetingKeyTypeEnum.CustomTargetingKeyType, ) status: custom_targeting_key_enums.CustomTargetingKeyStatusEnum.CustomTargetingKeyStatus = proto.Field( proto.ENUM, number=6, + optional=True, enum=custom_targeting_key_enums.CustomTargetingKeyStatusEnum.CustomTargetingKeyStatus, ) reportable_type: custom_targeting_key_enums.CustomTargetingKeyReportableTypeEnum.CustomTargetingKeyReportableType = proto.Field( proto.ENUM, number=7, + optional=True, enum=custom_targeting_key_enums.CustomTargetingKeyReportableTypeEnum.CustomTargetingKeyReportableType, ) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_targeting_key_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_targeting_key_service.py index 8eba47ead14b..1f1f799ec6c6 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_targeting_key_service.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_targeting_key_service.py @@ -124,8 +124,8 @@ class ListCustomTargetingKeysResponse(proto.Message): was included in the request, this reflects the total number after the filtering is applied. - ``total_size`` will not be calculated in the response unless - it has been included in a response field mask. The response + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response field mask can be provided to the method by using the URL parameter ``$fields`` or ``fields``, or by using the HTTP/gRPC header ``X-Goog-FieldMask``. diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_targeting_value_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_targeting_value_messages.py index 26319a3a966d..75c1cbe8595d 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_targeting_value_messages.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_targeting_value_messages.py @@ -32,6 +32,8 @@ class CustomTargetingValue(proto.Message): r"""The ``CustomTargetingValue`` resource. + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: name (str): Identifier. The resource name of the @@ -41,6 +43,8 @@ class CustomTargetingValue(proto.Message): Required. Immutable. The resource name of the ``CustomTargetingKey``. Format: ``networks/{network_code}/customTargetingKeys/{custom_targeting_key_id}`` + + This field is a member of `oneof`_ ``_custom_targeting_key``. ad_tag_name (str): Immutable. Name of the ``CustomTargetingValue``. Values can contain up to 40 characters each. You can use alphanumeric @@ -48,14 +52,22 @@ class CustomTargetingValue(proto.Message): +, #, \*, ~, ;, ^, (, ), <, >, [, ]. Values are not data-specific; all values are treated as strings. For example, instead of using "age>=18 AND <=34", try "18-34". + + This field is a member of `oneof`_ ``_ad_tag_name``. display_name (str): Optional. Descriptive name for the ``CustomTargetingValue``. + + This field is a member of `oneof`_ ``_display_name``. match_type (google.ads.admanager_v1.types.CustomTargetingValueMatchTypeEnum.CustomTargetingValueMatchType): Required. Immutable. The way in which the CustomTargetingValue.name strings will be matched. + + This field is a member of `oneof`_ ``_match_type``. status (google.ads.admanager_v1.types.CustomTargetingValueStatusEnum.CustomTargetingValueStatus): Output only. Status of the ``CustomTargetingValue``. + + This field is a member of `oneof`_ ``_status``. """ name: str = proto.Field( @@ -65,23 +77,28 @@ class CustomTargetingValue(proto.Message): custom_targeting_key: str = proto.Field( proto.STRING, number=8, + optional=True, ) ad_tag_name: str = proto.Field( proto.STRING, number=4, + optional=True, ) display_name: str = proto.Field( proto.STRING, number=5, + optional=True, ) match_type: custom_targeting_value_enums.CustomTargetingValueMatchTypeEnum.CustomTargetingValueMatchType = proto.Field( proto.ENUM, number=6, + optional=True, enum=custom_targeting_value_enums.CustomTargetingValueMatchTypeEnum.CustomTargetingValueMatchType, ) status: custom_targeting_value_enums.CustomTargetingValueStatusEnum.CustomTargetingValueStatus = proto.Field( proto.ENUM, number=7, + optional=True, enum=custom_targeting_value_enums.CustomTargetingValueStatusEnum.CustomTargetingValueStatus, ) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_targeting_value_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_targeting_value_service.py index 6792d95d9e76..3ce6719dffe4 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_targeting_value_service.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/custom_targeting_value_service.py @@ -124,8 +124,8 @@ class ListCustomTargetingValuesResponse(proto.Message): filter was included in the request, this reflects the total number after the filtering is applied. - ``total_size`` will not be calculated in the response unless - it has been included in a response field mask. The response + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response field mask can be provided to the method by using the URL parameter ``$fields`` or ``fields``, or by using the HTTP/gRPC header ``X-Goog-FieldMask``. diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/device_capability_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/device_capability_messages.py new file mode 100644 index 000000000000..8f5e4936f6e3 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/device_capability_messages.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 + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "DeviceCapability", + }, +) + + +class DeviceCapability(proto.Message): + r"""Represents a device capability. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + Identifier. The resource name of the ``DeviceCapability``. + Format: + ``networks/{network_code}/deviceCapabilities/{device_capability_id}`` + display_name (str): + Output only. The localized name of the device + capability. + + This field is a member of `oneof`_ ``_display_name``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/device_capability_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/device_capability_service.py new file mode 100644 index 000000000000..8fc82ca7f1b5 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/device_capability_service.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +from google.ads.admanager_v1.types import device_capability_messages + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "GetDeviceCapabilityRequest", + "ListDeviceCapabilitiesRequest", + "ListDeviceCapabilitiesResponse", + }, +) + + +class GetDeviceCapabilityRequest(proto.Message): + r"""Request object for ``GetDeviceCapability`` method. + + Attributes: + name (str): + Required. The resource name of the DeviceCapability. Format: + ``networks/{network_code}/deviceCapabilities/{device_capability_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListDeviceCapabilitiesRequest(proto.Message): + r"""Request object for ``ListDeviceCapabilities`` method. + + Attributes: + parent (str): + Required. The parent, which owns this collection of + DeviceCapabilities. Format: ``networks/{network_code}`` + page_size (int): + Optional. The maximum number of ``DeviceCapabilities`` to + return. The service may return fewer than this value. If + unspecified, at most 50 ``DeviceCapabilities`` will be + returned. The maximum value is 1000; values above 1000 will + be coerced to 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListDeviceCapabilities`` call. Provide this to retrieve + the subsequent page. + + When paginating, all other parameters provided to + ``ListDeviceCapabilities`` must match the call that provided + the page token. + filter (str): + Optional. Expression to filter the response. + See syntax details at + https://developers.google.com/ad-manager/api/beta/filters + order_by (str): + Optional. Expression to specify sorting + order. See syntax details at + https://developers.google.com/ad-manager/api/beta/filters#order + skip (int): + Optional. Number of individual resources to + skip while paginating. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + skip: int = proto.Field( + proto.INT32, + number=6, + ) + + +class ListDeviceCapabilitiesResponse(proto.Message): + r"""Response object for ``ListDeviceCapabilitiesRequest`` containing + matching ``DeviceCapability`` objects. + + Attributes: + device_capabilities (MutableSequence[google.ads.admanager_v1.types.DeviceCapability]): + The ``DeviceCapability`` objects from the specified network. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + total_size (int): + Total number of ``DeviceCapability`` objects. If a filter + was included in the request, this reflects the total number + after the filtering is applied. + + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response + field mask can be provided to the method by using the URL + parameter ``$fields`` or ``fields``, or by using the + HTTP/gRPC header ``X-Goog-FieldMask``. + + For more information, see + https://developers.google.com/ad-manager/api/beta/field-masks + """ + + @property + def raw_page(self): + return self + + device_capabilities: MutableSequence[ + device_capability_messages.DeviceCapability + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=device_capability_messages.DeviceCapability, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/device_category_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/device_category_service.py index 747a5dd22a45..205639be4dc1 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/device_category_service.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/device_category_service.py @@ -57,8 +57,8 @@ class ListDeviceCategoriesRequest(proto.Message): Optional. The maximum number of ``DeviceCategories`` to return. The service may return fewer than this value. If unspecified, at most 50 ``DeviceCategories`` will be - returned. The maximum value is 1000; values above 1000 will - be coerced to 1000. + returned. The maximum value is 1000; values greater than + 1000 will be coerced to 1000. page_token (str): Optional. A page token, received from a previous ``ListDeviceCategories`` call. Provide this to retrieve the @@ -122,8 +122,8 @@ class ListDeviceCategoriesResponse(proto.Message): included in the request, this reflects the total number after the filtering is applied. - ``total_size`` will not be calculated in the response unless - it has been included in a response field mask. The response + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response field mask can be provided to the method by using the URL parameter ``$fields`` or ``fields``, or by using the HTTP/gRPC header ``X-Goog-FieldMask``. diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/device_manufacturer_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/device_manufacturer_messages.py new file mode 100644 index 000000000000..fb431b8ef30c --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/device_manufacturer_messages.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 + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "DeviceManufacturer", + }, +) + + +class DeviceManufacturer(proto.Message): + r"""Represents a device manufacturer. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + Identifier. The resource name of the ``DeviceManufacturer``. + Format: + ``networks/{network_code}/deviceManufacturers/{device_manufacturer}`` + display_name (str): + Output only. The localized name of the device + manufacturer. + + This field is a member of `oneof`_ ``_display_name``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/device_manufacturer_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/device_manufacturer_service.py new file mode 100644 index 000000000000..b0be43851ac1 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/device_manufacturer_service.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +from google.ads.admanager_v1.types import device_manufacturer_messages + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "GetDeviceManufacturerRequest", + "ListDeviceManufacturersRequest", + "ListDeviceManufacturersResponse", + }, +) + + +class GetDeviceManufacturerRequest(proto.Message): + r"""Request object for ``GetDeviceManufacturer`` method. + + Attributes: + name (str): + Required. The resource name of the DeviceManufacturer. + Format: + ``networks/{network_code}/deviceManufacturers/{device_manufacturer_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListDeviceManufacturersRequest(proto.Message): + r"""Request object for ``ListDeviceManufacturers`` method. + + Attributes: + parent (str): + Required. The parent, which owns this collection of + DeviceManufacturers. Format: ``networks/{network_code}`` + page_size (int): + Optional. The maximum number of ``DeviceManufacturers`` to + return. The service may return fewer than this value. If + unspecified, at most 50 ``DeviceManufacturers`` will be + returned. The maximum value is 1000; values above 1000 will + be coerced to 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListDeviceManufacturers`` call. Provide this to retrieve + the subsequent page. + + When paginating, all other parameters provided to + ``ListDeviceManufacturers`` must match the call that + provided the page token. + filter (str): + Optional. Expression to filter the response. + See syntax details at + https://developers.google.com/ad-manager/api/beta/filters + order_by (str): + Optional. Expression to specify sorting + order. See syntax details at + https://developers.google.com/ad-manager/api/beta/filters#order + skip (int): + Optional. Number of individual resources to + skip while paginating. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + skip: int = proto.Field( + proto.INT32, + number=6, + ) + + +class ListDeviceManufacturersResponse(proto.Message): + r"""Response object for ``ListDeviceManufacturersRequest`` containing + matching ``DeviceManufacturer`` objects. + + Attributes: + device_manufacturers (MutableSequence[google.ads.admanager_v1.types.DeviceManufacturer]): + The ``DeviceManufacturer`` objects from the specified + network. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + total_size (int): + Total number of ``DeviceManufacturer`` objects. If a filter + was included in the request, this reflects the total number + after the filtering is applied. + + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response + field mask can be provided to the method by using the URL + parameter ``$fields`` or ``fields``, or by using the + HTTP/gRPC header ``X-Goog-FieldMask``. + + For more information, see + https://developers.google.com/ad-manager/api/beta/field-masks + """ + + @property + def raw_page(self): + return self + + device_manufacturers: MutableSequence[ + device_manufacturer_messages.DeviceManufacturer + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=device_manufacturer_messages.DeviceManufacturer, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/entity_signals_mapping_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/entity_signals_mapping_service.py index 58ade5063cd8..c0018fd28171 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/entity_signals_mapping_service.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/entity_signals_mapping_service.py @@ -184,8 +184,8 @@ class ListEntitySignalsMappingsResponse(proto.Message): included in the request, this reflects the total number after the filtering is applied. - ``total_size`` will not be calculated in the response unless - it has been included in a response field mask. The response + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response field mask can be provided to the method by using the URL parameter ``$fields`` or ``fields``, or by using the HTTP/gRPC header ``X-Goog-FieldMask``. diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/exchange_syndication_product_enum.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/exchange_syndication_product_enum.py new file mode 100644 index 000000000000..88e5f971c29b --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/exchange_syndication_product_enum.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 + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "ExchangeSyndicationProductEnum", + }, +) + + +class ExchangeSyndicationProductEnum(proto.Message): + r"""Wrapper message for + [ExchangeSyndicationProduct][google.ads.admanager.v1.ExchangeSyndicationProductEnum.ExchangeSyndicationProduct] + + """ + + class ExchangeSyndicationProduct(proto.Enum): + r"""Ad Exchange syndication product. + + Values: + EXCHANGE_SYNDICATION_PRODUCT_UNSPECIFIED (0): + No value specified + DISPLAY (1): + Property serves in-browser. + MOBILE_APP (2): + Property serves on mobile applications + (includes JS and SDK). + VIDEO_AND_AUDIO (3): + Property serves video (includes audio). + GAMES (4): + Property serves for games. + """ + EXCHANGE_SYNDICATION_PRODUCT_UNSPECIFIED = 0 + DISPLAY = 1 + MOBILE_APP = 2 + VIDEO_AND_AUDIO = 3 + GAMES = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/geo_target_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/geo_target_service.py index 98fe6266b1b4..b69ec8abc7df 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/geo_target_service.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/geo_target_service.py @@ -57,8 +57,8 @@ class ListGeoTargetsRequest(proto.Message): Optional. The maximum number of ``GeoTargets`` to return. The service may return fewer than this value. If unspecified, at most 50 ``GeoTargets`` will be returned. The - maximum value is 1000; values above 1000 will be coerced to - 1000. + maximum value is 1000; values greater than 1000 will be + coerced to 1000. page_token (str): Optional. A page token, received from a previous ``ListGeoTargets`` call. Provide this to retrieve the @@ -122,8 +122,8 @@ class ListGeoTargetsResponse(proto.Message): included in the request, this reflects the total number after the filtering is applied. - ``total_size`` will not be calculated in the response unless - it has been included in a response field mask. The response + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response field mask can be provided to the method by using the URL parameter ``$fields`` or ``fields``, or by using the HTTP/gRPC header ``X-Goog-FieldMask``. diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/mobile_carrier_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/mobile_carrier_messages.py new file mode 100644 index 000000000000..c337e597bd54 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/mobile_carrier_messages.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "MobileCarrier", + }, +) + + +class MobileCarrier(proto.Message): + r"""Represents a mobile carrier. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + Identifier. The resource name of the ``MobileCarrier``. + Format: + ``networks/{network_code}/mobileCarriers/{mobile_carrier}`` + display_name (str): + Output only. The localized name of the mobile + carrier. + + This field is a member of `oneof`_ ``_display_name``. + region_code (str): + Output only. The region code of the mobile + carrier. + + This field is a member of `oneof`_ ``_region_code``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + region_code: str = proto.Field( + proto.STRING, + number=4, + optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/mobile_carrier_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/mobile_carrier_service.py new file mode 100644 index 000000000000..e1b13c95553e --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/mobile_carrier_service.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +from google.ads.admanager_v1.types import mobile_carrier_messages + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "GetMobileCarrierRequest", + "ListMobileCarriersRequest", + "ListMobileCarriersResponse", + }, +) + + +class GetMobileCarrierRequest(proto.Message): + r"""Request object for ``GetMobileCarrier`` method. + + Attributes: + name (str): + Required. The resource name of the MobileCarrier. Format: + ``networks/{network_code}/mobileCarriers/{mobile_carrier_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListMobileCarriersRequest(proto.Message): + r"""Request object for ``ListMobileCarriers`` method. + + Attributes: + parent (str): + Required. The parent, which owns this collection of + MobileCarriers. Format: ``networks/{network_code}`` + page_size (int): + Optional. The maximum number of ``MobileCarriers`` to + return. The service may return fewer than this value. If + unspecified, at most 50 ``MobileCarriers`` will be returned. + The maximum value is 1000; values greater than 1000 will be + coerced to 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListMobileCarriers`` call. Provide this to retrieve the + subsequent page. + + When paginating, all other parameters provided to + ``ListMobileCarriers`` must match the call that provided the + page token. + filter (str): + Optional. Expression to filter the response. + See syntax details at + https://developers.google.com/ad-manager/api/beta/filters + order_by (str): + Optional. Expression to specify sorting + order. See syntax details at + https://developers.google.com/ad-manager/api/beta/filters#order + skip (int): + Optional. Number of individual resources to + skip while paginating. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + skip: int = proto.Field( + proto.INT32, + number=6, + ) + + +class ListMobileCarriersResponse(proto.Message): + r"""Response object for ``ListMobileCarriersRequest`` containing + matching ``MobileCarrier`` objects. + + Attributes: + mobile_carriers (MutableSequence[google.ads.admanager_v1.types.MobileCarrier]): + The ``MobileCarrier`` objects from the specified network. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + total_size (int): + Total number of ``MobileCarrier`` objects. If a filter was + included in the request, this reflects the total number + after the filtering is applied. + + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response + field mask can be provided to the method by using the URL + parameter ``$fields`` or ``fields``, or by using the + HTTP/gRPC header ``X-Goog-FieldMask``. + + For more information, see + https://developers.google.com/ad-manager/api/beta/field-masks + """ + + @property + def raw_page(self): + return self + + mobile_carriers: MutableSequence[ + mobile_carrier_messages.MobileCarrier + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=mobile_carrier_messages.MobileCarrier, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/mobile_device_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/mobile_device_messages.py new file mode 100644 index 000000000000..5621b3003a2c --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/mobile_device_messages.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 + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "MobileDevice", + }, +) + + +class MobileDevice(proto.Message): + r"""Represents a mobile device. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + Identifier. The resource name of the ``MobileDevice``. + Format: + ``networks/{network_code}/mobileDevices/{mobile_device}`` + display_name (str): + Output only. The localized name of the mobile + device. + + This field is a member of `oneof`_ ``_display_name``. + manufacturer (str): + Output only. The manufacturer associated with the mobile + device. Format: + ``networks/{network_code}/deviceManufacturers/{device_manufacturer}`` + + This field is a member of `oneof`_ ``_manufacturer``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + manufacturer: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/mobile_device_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/mobile_device_service.py new file mode 100644 index 000000000000..c9c15594fccd --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/mobile_device_service.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +from google.ads.admanager_v1.types import mobile_device_messages + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "GetMobileDeviceRequest", + "ListMobileDevicesRequest", + "ListMobileDevicesResponse", + }, +) + + +class GetMobileDeviceRequest(proto.Message): + r"""Request object for ``GetMobileDevice`` method. + + Attributes: + name (str): + Required. The resource name of the MobileDevice. Format: + ``networks/{network_code}/mobileDevices/{mobile_device_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListMobileDevicesRequest(proto.Message): + r"""Request object for ``ListMobileDevices`` method. + + Attributes: + parent (str): + Required. The parent, which owns this collection of + MobileDevices. Format: ``networks/{network_code}`` + page_size (int): + Optional. The maximum number of ``MobileDevices`` to return. + The service may return fewer than this value. If + unspecified, at most 50 ``MobileDevices`` will be returned. + The maximum value is 1000; values greater than 1000 will be + coerced to 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListMobileDevices`` call. Provide this to retrieve the + subsequent page. + + When paginating, all other parameters provided to + ``ListMobileDevices`` must match the call that provided the + page token. + filter (str): + Optional. Expression to filter the response. + See syntax details at + https://developers.google.com/ad-manager/api/beta/filters + order_by (str): + Optional. Expression to specify sorting + order. See syntax details at + https://developers.google.com/ad-manager/api/beta/filters#order + skip (int): + Optional. Number of individual resources to + skip while paginating. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + skip: int = proto.Field( + proto.INT32, + number=6, + ) + + +class ListMobileDevicesResponse(proto.Message): + r"""Response object for ``ListMobileDevicesRequest`` containing matching + ``MobileDevice`` objects. + + Attributes: + mobile_devices (MutableSequence[google.ads.admanager_v1.types.MobileDevice]): + The ``MobileDevice`` objects from the specified network. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + total_size (int): + Total number of ``MobileDevice`` objects. If a filter was + included in the request, this reflects the total number + after the filtering is applied. + + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response + field mask can be provided to the method by using the URL + parameter ``$fields`` or ``fields``, or by using the + HTTP/gRPC header ``X-Goog-FieldMask``. + + For more information, see + https://developers.google.com/ad-manager/api/beta/field-masks + """ + + @property + def raw_page(self): + return self + + mobile_devices: MutableSequence[ + mobile_device_messages.MobileDevice + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=mobile_device_messages.MobileDevice, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/mobile_device_submodel_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/mobile_device_submodel_messages.py new file mode 100644 index 000000000000..f2652f7a8c83 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/mobile_device_submodel_messages.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 + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "MobileDeviceSubmodel", + }, +) + + +class MobileDeviceSubmodel(proto.Message): + r"""Represents a mobile device submodel. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + Identifier. The resource name of the + ``MobileDeviceSubmodel``. Format: + ``networks/{network_code}/mobileDeviceSubmodels/{mobile_device_submodel}`` + display_name (str): + Output only. The display name of the mobile + device submodel. + + This field is a member of `oneof`_ ``_display_name``. + mobile_device (str): + Output only. The mobile device associated with the submodel. + Format: + ``networks/{network_code}/mobileDevices/{mobile_device}`` + + This field is a member of `oneof`_ ``_mobile_device``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + mobile_device: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/mobile_device_submodel_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/mobile_device_submodel_service.py new file mode 100644 index 000000000000..96b746b06b2f --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/mobile_device_submodel_service.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +from google.ads.admanager_v1.types import mobile_device_submodel_messages + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "GetMobileDeviceSubmodelRequest", + "ListMobileDeviceSubmodelsRequest", + "ListMobileDeviceSubmodelsResponse", + }, +) + + +class GetMobileDeviceSubmodelRequest(proto.Message): + r"""Request object for ``GetMobileDeviceSubmodel`` method. + + Attributes: + name (str): + Required. The resource name of the MobileDeviceSubmodel. + Format: + ``networks/{network_code}/mobileDeviceSubmodels/{mobile_device_submodel_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListMobileDeviceSubmodelsRequest(proto.Message): + r"""Request object for ``ListMobileDeviceSubmodels`` method. + + Attributes: + parent (str): + Required. The parent, which owns this collection of + MobileDeviceSubmodels. Format: ``networks/{network_code}`` + page_size (int): + Optional. The maximum number of ``MobileDeviceSubmodels`` to + return. The service may return fewer than this value. If + unspecified, at most 50 ``MobileDeviceSubmodels`` will be + returned. The maximum value is 1000; values above 1000 will + be coerced to 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListMobileDeviceSubmodels`` call. Provide this to retrieve + the subsequent page. + + When paginating, all other parameters provided to + ``ListMobileDeviceSubmodels`` must match the call that + provided the page token. + filter (str): + Optional. Expression to filter the response. + See syntax details at + https://developers.google.com/ad-manager/api/beta/filters + order_by (str): + Optional. Expression to specify sorting + order. See syntax details at + https://developers.google.com/ad-manager/api/beta/filters#order + skip (int): + Optional. Number of individual resources to + skip while paginating. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + skip: int = proto.Field( + proto.INT32, + number=6, + ) + + +class ListMobileDeviceSubmodelsResponse(proto.Message): + r"""Response object for ``ListMobileDeviceSubmodelsRequest`` containing + matching ``MobileDeviceSubmodel`` objects. + + Attributes: + mobile_device_submodels (MutableSequence[google.ads.admanager_v1.types.MobileDeviceSubmodel]): + The ``MobileDeviceSubmodel`` objects from the specified + network. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + total_size (int): + Total number of ``MobileDeviceSubmodel`` objects. If a + filter was included in the request, this reflects the total + number after the filtering is applied. + + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response + field mask can be provided to the method by using the URL + parameter ``$fields`` or ``fields``, or by using the + HTTP/gRPC header ``X-Goog-FieldMask``. + + For more information, see + https://developers.google.com/ad-manager/api/beta/field-masks + """ + + @property + def raw_page(self): + return self + + mobile_device_submodels: MutableSequence[ + mobile_device_submodel_messages.MobileDeviceSubmodel + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=mobile_device_submodel_messages.MobileDeviceSubmodel, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/operating_system_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/operating_system_service.py index ca5baf1cbda3..596e2872af86 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/operating_system_service.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/operating_system_service.py @@ -57,8 +57,8 @@ class ListOperatingSystemsRequest(proto.Message): Optional. The maximum number of ``OperatingSystems`` to return. The service may return fewer than this value. If unspecified, at most 50 ``OperatingSystems`` will be - returned. The maximum value is 1000; values above 1000 will - be coerced to 1000. + returned. The maximum value is 1000; values greater than + 1000 will be coerced to 1000. page_token (str): Optional. A page token, received from a previous ``ListOperatingSystems`` call. Provide this to retrieve the @@ -122,8 +122,8 @@ class ListOperatingSystemsResponse(proto.Message): included in the request, this reflects the total number after the filtering is applied. - ``total_size`` will not be calculated in the response unless - it has been included in a response field mask. The response + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response field mask can be provided to the method by using the URL parameter ``$fields`` or ``fields``, or by using the HTTP/gRPC header ``X-Goog-FieldMask``. diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/operating_system_version_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/operating_system_version_service.py index afd179c40852..5ba0b1ea8c06 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/operating_system_version_service.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/operating_system_version_service.py @@ -58,8 +58,8 @@ class ListOperatingSystemVersionsRequest(proto.Message): Optional. The maximum number of ``OperatingSystemVersions`` to return. The service may return fewer than this value. If unspecified, at most 50 ``OperatingSystemVersions`` will be - returned. The maximum value is 1000; values above 1000 will - be coerced to 1000. + returned. The maximum value is 1000; values greater than + 1000 will be coerced to 1000. page_token (str): Optional. A page token, received from a previous ``ListOperatingSystemVersions`` call. Provide this to @@ -124,8 +124,8 @@ class ListOperatingSystemVersionsResponse(proto.Message): filter was included in the request, this reflects the total number after the filtering is applied. - ``total_size`` will not be calculated in the response unless - it has been included in a response field mask. The response + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response field mask can be provided to the method by using the URL parameter ``$fields`` or ``fields``, or by using the HTTP/gRPC header ``X-Goog-FieldMask``. diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/order_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/order_messages.py index 5ba6a1749bf6..4eee8071d5ec 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/order_messages.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/order_messages.py @@ -90,8 +90,8 @@ class Order(proto.Message): "networks/{network_code}/teams/{team_id}". creator (str): Output only. The resource name of the User who created the - Order on behalf of the advertiser. This value is assigned by - Google. Format: "networks/{network_code}/users/{user_id}". + Order on behalf of the advertiser. Format: + "networks/{network_code}/users/{user_id}". This field is a member of `oneof`_ ``_creator``. currency_code (str): @@ -102,16 +102,16 @@ class Order(proto.Message): This field is a member of `oneof`_ ``_currency_code``. start_time (google.protobuf.timestamp_pb2.Timestamp): Output only. The instant at which the Order and its - associated line items are eligible to begin serving. This - attribute is derived from the line item of the order that - has the earliest LineItem.start_time. + associated Line items are eligible to begin serving. This + attribute is derived from the Line item of the order that + has the earliest ``LineItem.start_time``. This field is a member of `oneof`_ ``_start_time``. end_time (google.protobuf.timestamp_pb2.Timestamp): Output only. The instant at which the Order and its - associated line items stop being served. This attribute is - derived from the line item of the order that has the latest - LineItem.end_time. + associated Line items stop being served. This attribute is + derived from the Line item of the order that has the latest + ``LineItem.end_time``. This field is a member of `oneof`_ ``_end_time``. unlimited_end_time (bool): diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/order_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/order_service.py index 1bf8719ff530..1dd5ade3335b 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/order_service.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/order_service.py @@ -57,7 +57,7 @@ class ListOrdersRequest(proto.Message): Optional. The maximum number of ``Orders`` to return. The service may return fewer than this value. If unspecified, at most 50 ``Orders`` will be returned. The maximum value is - 1000; values above 1000 will be coerced to 1000. + 1000; values greater than 1000 will be coerced to 1000. page_token (str): Optional. A page token, received from a previous ``ListOrders`` call. Provide this to retrieve the subsequent @@ -121,8 +121,8 @@ class ListOrdersResponse(proto.Message): request, this reflects the total number after the filtering is applied. - ``total_size`` will not be calculated in the response unless - it has been included in a response field mask. The response + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response field mask can be provided to the method by using the URL parameter ``$fields`` or ``fields``, or by using the HTTP/gRPC header ``X-Goog-FieldMask``. diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/placement_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/placement_service.py index 0c8ed099d0d3..2b5a377e8c15 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/placement_service.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/placement_service.py @@ -17,6 +17,7 @@ from typing import MutableMapping, MutableSequence +from google.protobuf import field_mask_pb2 # type: ignore import proto # type: ignore from google.ads.admanager_v1.types import placement_messages @@ -27,6 +28,18 @@ "GetPlacementRequest", "ListPlacementsRequest", "ListPlacementsResponse", + "CreatePlacementRequest", + "BatchCreatePlacementsRequest", + "BatchCreatePlacementsResponse", + "UpdatePlacementRequest", + "BatchUpdatePlacementsRequest", + "BatchUpdatePlacementsResponse", + "BatchActivatePlacementsRequest", + "BatchActivatePlacementsResponse", + "BatchDeactivatePlacementsRequest", + "BatchDeactivatePlacementsResponse", + "BatchArchivePlacementsRequest", + "BatchArchivePlacementsResponse", }, ) @@ -57,8 +70,8 @@ class ListPlacementsRequest(proto.Message): Optional. The maximum number of ``Placements`` to return. The service may return fewer than this value. If unspecified, at most 50 ``Placements`` will be returned. The - maximum value is 1000; values above 1000 will be coerced to - 1000. + maximum value is 1000; values greater than 1000 will be + coerced to 1000. page_token (str): Optional. A page token, received from a previous ``ListPlacements`` call. Provide this to retrieve the @@ -122,8 +135,8 @@ class ListPlacementsResponse(proto.Message): included in the request, this reflects the total number after the filtering is applied. - ``total_size`` will not be calculated in the response unless - it has been included in a response field mask. The response + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response field mask can be provided to the method by using the URL parameter ``$fields`` or ``fields``, or by using the HTTP/gRPC header ``X-Goog-FieldMask``. @@ -151,4 +164,209 @@ def raw_page(self): ) +class CreatePlacementRequest(proto.Message): + r"""Request object for ``CreatePlacement`` method. + + Attributes: + parent (str): + Required. The parent resource where this ``Placement`` will + be created. Format: ``networks/{network_code}`` + placement (google.ads.admanager_v1.types.Placement): + Required. The ``Placement`` to create. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + placement: placement_messages.Placement = proto.Field( + proto.MESSAGE, + number=2, + message=placement_messages.Placement, + ) + + +class BatchCreatePlacementsRequest(proto.Message): + r"""Request object for ``BatchCreatePlacements`` method. + + Attributes: + parent (str): + Required. The parent resource where the ``Placement``\ s + will be created. Format: ``networks/{network_code}`` The + parent field in the CreatePlacementRequest messages match + this field. + requests (MutableSequence[google.ads.admanager_v1.types.CreatePlacementRequest]): + Required. The ``Placement`` objects to create. A maximum of + 100 objects can be created in a batch. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + requests: MutableSequence["CreatePlacementRequest"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="CreatePlacementRequest", + ) + + +class BatchCreatePlacementsResponse(proto.Message): + r"""Response object for ``BatchCreatePlacements`` method. + + Attributes: + placements (MutableSequence[google.ads.admanager_v1.types.Placement]): + The ``Placement`` objects created. + """ + + placements: MutableSequence[placement_messages.Placement] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=placement_messages.Placement, + ) + + +class UpdatePlacementRequest(proto.Message): + r"""Request object for ``UpdatePlacement`` method. + + Attributes: + placement (google.ads.admanager_v1.types.Placement): + Required. The ``Placement`` to update. + + The ``Placement``'s name is used to identify the + ``Placement`` to update. Format: + ``networks/{network_code}/placements/{placement_id}`` + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Required. The list of fields to update. + """ + + placement: placement_messages.Placement = proto.Field( + proto.MESSAGE, + number=1, + message=placement_messages.Placement, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class BatchUpdatePlacementsRequest(proto.Message): + r"""Request object for ``BatchUpdatePlacements`` method. + + Attributes: + parent (str): + Required. The parent resource where ``Placements`` will be + updated. Format: ``networks/{network_code}`` The parent + field in the UpdatePlacementsRequest must match this field. + requests (MutableSequence[google.ads.admanager_v1.types.UpdatePlacementRequest]): + Required. The ``Placement`` objects to update. A maximum of + 100 objects can be updated in a batch. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + requests: MutableSequence["UpdatePlacementRequest"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="UpdatePlacementRequest", + ) + + +class BatchUpdatePlacementsResponse(proto.Message): + r"""Response object for ``BatchUpdatePlacements`` method. + + Attributes: + placements (MutableSequence[google.ads.admanager_v1.types.Placement]): + The ``Placement`` objects updated. + """ + + placements: MutableSequence[placement_messages.Placement] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=placement_messages.Placement, + ) + + +class BatchActivatePlacementsRequest(proto.Message): + r"""Request message for ``BatchActivatePlacements`` method. + + Attributes: + parent (str): + Required. Format: ``networks/{network_code}`` + names (MutableSequence[str]): + Required. The names of the ``Placement`` objects to + activate. Format: + ``networks/{network_code}/placements/{placement_id}`` + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + +class BatchActivatePlacementsResponse(proto.Message): + r"""Response object for ``BatchActivatePlacements`` method.""" + + +class BatchDeactivatePlacementsRequest(proto.Message): + r"""Request message for ``BatchDeactivatePlacements`` method. + + Attributes: + parent (str): + Required. Format: ``networks/{network_code}`` + names (MutableSequence[str]): + Required. The names of the ``Placement`` objects to + deactivate. Format: + ``networks/{network_code}/placements/{placement_id}`` + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + +class BatchDeactivatePlacementsResponse(proto.Message): + r"""Response object for ``BatchDeactivatePlacements`` method.""" + + +class BatchArchivePlacementsRequest(proto.Message): + r"""Request message for ``BatchArchivePlacements`` method. + + Attributes: + parent (str): + Required. Format: ``networks/{network_code}`` + names (MutableSequence[str]): + Required. The names of the ``Placement`` objects to archive. + Format: + ``networks/{network_code}/placements/{placement_id}`` + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + +class BatchArchivePlacementsResponse(proto.Message): + r"""Response object for ``BatchArchivePlacements`` method.""" + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/private_auction_deal_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/private_auction_deal_service.py index 4451e48df7a3..5640ff44e418 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/private_auction_deal_service.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/private_auction_deal_service.py @@ -61,8 +61,8 @@ class ListPrivateAuctionDealsRequest(proto.Message): Optional. The maximum number of ``PrivateAuctionDeals`` to return. The service may return fewer than this value. If unspecified, at most 50 ``PrivateAuctionDeals`` will be - returned. The maximum value is 1000; values above 1000 will - be coerced to 1000. + returned. The maximum value is 1000; values greater than + 1000 will be coerced to 1000. page_token (str): Optional. A page token, received from a previous ``ListPrivateAuctionDeals`` call. Provide this to retrieve @@ -127,8 +127,8 @@ class ListPrivateAuctionDealsResponse(proto.Message): was included in the request, this reflects the total number after the filtering is applied. - ``total_size`` will not be calculated in the response unless - it has been included in a response field mask. The response + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response field mask can be provided to the method by using the URL parameter ``$fields`` or ``fields``, or by using the HTTP/gRPC header ``X-Goog-FieldMask``. diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/private_auction_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/private_auction_service.py index 0cf5a4894ad2..aa687e105e0f 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/private_auction_service.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/private_auction_service.py @@ -60,8 +60,8 @@ class ListPrivateAuctionsRequest(proto.Message): Optional. The maximum number of ``PrivateAuctions`` to return. The service may return fewer than this value. If unspecified, at most 50 ``PrivateAuctions`` will be - returned. The maximum value is 1000; values above 1000 will - be coerced to 1000. + returned. The maximum value is 1000; values greater than + 1000 will be coerced to 1000. page_token (str): Optional. A page token, received from a previous ``ListPrivateAuctions`` call. Provide this to retrieve the @@ -125,8 +125,8 @@ class ListPrivateAuctionsResponse(proto.Message): included in the request, this reflects the total number after the filtering is applied. - ``total_size`` will not be calculated in the response unless - it has been included in a response field mask. The response + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response field mask can be provided to the method by using the URL parameter ``$fields`` or ``fields``, or by using the HTTP/gRPC header ``X-Goog-FieldMask``. diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/programmatic_buyer_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/programmatic_buyer_service.py index 95927c97d8f7..fc10aac16439 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/programmatic_buyer_service.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/programmatic_buyer_service.py @@ -124,8 +124,8 @@ class ListProgrammaticBuyersResponse(proto.Message): was included in the request, this reflects the total number after the filtering is applied. - ``total_size`` will not be calculated in the response unless - it has been included in a response field mask. The response + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response field mask can be provided to the method by using the URL parameter ``$fields`` or ``fields``, or by using the HTTP/gRPC header ``X-Goog-FieldMask``. diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/report_definition.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/report_definition.py new file mode 100644 index 000000000000..b601e57c51a9 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/report_definition.py @@ -0,0 +1,11794 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +from google.type import date_pb2 # type: ignore +import proto # type: ignore + +from google.ads.admanager_v1.types import report_value + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "ReportDefinition", + }, +) + + +class ReportDefinition(proto.Message): + r"""The definition of how a report should be run. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + dimensions (MutableSequence[google.ads.admanager_v1.types.ReportDefinition.Dimension]): + Required. The list of dimensions to report + on. If empty, the report will have no + dimensions, and any metrics will be totals. + metrics (MutableSequence[google.ads.admanager_v1.types.ReportDefinition.Metric]): + Required. The list of metrics to report on. + If empty, the report will have no metrics. + filters (MutableSequence[google.ads.admanager_v1.types.ReportDefinition.Filter]): + Optional. The filters for this report. + time_zone_source (google.ads.admanager_v1.types.ReportDefinition.TimeZoneSource): + Optional. Where to get the time zone for this report. + Defaults to using the network time zone setting (PUBLISHER). + If source is PROVIDED, the time_zone field in the report + definition must also set a time zone. + time_zone (str): + Optional. If time_zone_source is PROVIDED, this is the time + zone to use for this report. Leave empty for any other time + zone source. Time zone in IANA format. For example, + "America/New_York". + currency_code (str): + Optional. The ISO 4217 currency code for this + report. Defaults to publisher currency code if + not specified. + date_range (google.ads.admanager_v1.types.ReportDefinition.DateRange): + Required. The primary date range of this + report. + comparison_date_range (google.ads.admanager_v1.types.ReportDefinition.DateRange): + Optional. The comparison date range of this + report. If unspecified, the report won't have + any comparison metrics. + + This field is a member of `oneof`_ ``_comparison_date_range``. + custom_dimension_key_ids (MutableSequence[int]): + Optional. Custom Dimension keys that represent + CUSTOM_DIMENSION\_\* dimensions. The index of this repeated + field corresponds to the index on each dimension. For + example, custom_dimension_key_ids[0] describes + CUSTOM_DIMENSION_0_VALUE_ID and CUSTOM_DIMENSION_0_VALUE. + line_item_custom_field_ids (MutableSequence[int]): + Optional. Custom field IDs that represent + LINE_ITEM_CUSTOM_FIELD\_\* dimensions. The index of this + repeated field corresponds to the index on each dimension. + For example, line_item_custom_field_ids[0] describes + LINE_ITEM_CUSTOM_FIELD_0_OPTION_ID and + LINE_ITEM_CUSTOM_FIELD_0_VALUE. + order_custom_field_ids (MutableSequence[int]): + Optional. Custom field IDs that represent + ORDER_CUSTOM_FIELD\_\* dimensions. The index of this + repeated field corresponds to the index on each dimension. + For example, order_custom_field_ids[0] describes + ORDER_CUSTOM_FIELD_0_OPTION_ID and + ORDER_CUSTOM_FIELD_0_VALUE. + creative_custom_field_ids (MutableSequence[int]): + Optional. Custom field IDs that represent + CREATIVE_CUSTOM_FIELD\_\* dimensions. The index of this + repeated field corresponds to the index on each dimension. + For example, creative_custom_field_ids[0] describes + CREATIVE_CUSTOM_FIELD_0_OPTION_ID and + CREATIVE_CUSTOM_FIELD_0_VALUE. + report_type (google.ads.admanager_v1.types.ReportDefinition.ReportType): + Required. The type of this report. + time_period_column (google.ads.admanager_v1.types.ReportDefinition.TimePeriodColumn): + Optional. Include a time period column to introduce + comparison columns in the report for each generated period. + For example, set to "QUARTERS" here to have a column for + each quarter present in the primary date range. If "PREVIOUS + PERIOD" is specified in comparison_date_range, then each + quarter column will also include comparison values for its + relative previous quarter. + flags (MutableSequence[google.ads.admanager_v1.types.ReportDefinition.Flag]): + Optional. List of flags for this report. Used + to flag rows in a result set based on a set of + defined filters. + sorts (MutableSequence[google.ads.admanager_v1.types.ReportDefinition.Sort]): + Optional. Default sorts to apply to this + report. + """ + + class ReportType(proto.Enum): + r"""Supported report types. + + Values: + REPORT_TYPE_UNSPECIFIED (0): + Default value. This value is unused. + HISTORICAL (1): + Historical. + REACH (5): + Reach. + PRIVACY_AND_MESSAGING (6): + Privacy and messaging. + AD_SPEED (13): + Ad speed. + """ + REPORT_TYPE_UNSPECIFIED = 0 + HISTORICAL = 1 + REACH = 5 + PRIVACY_AND_MESSAGING = 6 + AD_SPEED = 13 + + class Dimension(proto.Enum): + r"""Reporting dimensions. + + Values: + DIMENSION_UNSPECIFIED (0): + Default value. This value is unused. + ACTIVE_VIEW_MEASUREMENT_SOURCE (575): + The measurement source of a video ad. + + Corresponds to "Active View measurement source value" in the + Ad Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + ACTIVE_VIEW_MEASUREMENT_SOURCE_NAME (576): + Active View measurement source localized name. + + Corresponds to "Active View measurement source" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + ADVERTISER_CREDIT_STATUS (475): + Advertiser credit status ENUM + + Corresponds to "Advertiser credit status value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``ENUM`` + ADVERTISER_CREDIT_STATUS_NAME (476): + Advertiser credit status locallized name + + Corresponds to "Advertiser credit status" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``STRING`` + ADVERTISER_DOMAIN_NAME (242): + The domain name of the advertiser. + + Corresponds to "Advertiser domain" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + ADVERTISER_EXTERNAL_ID (228): + The ID used in an external system for advertiser + identification + + Corresponds to "Advertiser external ID" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + ADVERTISER_ID (131): + The ID of an advertiser company assigned to an order + + Corresponds to "Advertiser ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + ADVERTISER_LABELS (230): + Labels applied to the advertiser can be used for either + competitive exclusion or ad exclusion + + Corresponds to "Advertiser labels" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING_LIST`` + ADVERTISER_LABEL_IDS (229): + Label ids applied to the advertiser can be used for either + competitive exclusion or ad exclusion + + Corresponds to "Advertiser label IDs" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``IDENTIFIER_LIST`` + ADVERTISER_NAME (132): + The name of an advertiser company assigned to an order + + Corresponds to "Advertiser" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``STRING`` + ADVERTISER_PRIMARY_CONTACT (227): + The name of the contact associated with an advertiser + company + + Corresponds to "Advertiser primary contact" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + ADVERTISER_STATUS (471): + Advertiser status ENUM + + Corresponds to "Advertiser status value" in the Ad Manager + UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + ADVERTISER_STATUS_NAME (472): + Advertiser status locallized name + + Corresponds to "Advertiser status" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + ADVERTISER_TYPE (473): + Advertiser type ENUM + + Corresponds to "Advertiser type value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``ENUM`` + ADVERTISER_TYPE_NAME (474): + Advertiser type locallized name + + Corresponds to "Advertiser type" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``STRING`` + ADVERTISER_VERTICAL (580): + The category of an advertiser, such as Arts & Entertainment + or Travel & Tourism. + + Corresponds to "Advertiser vertical" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + ADX_PRODUCT (499): + Classification of different Ad Exchange products. + + Corresponds to "Ad Exchange product value" in the Ad Manager + UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + ADX_PRODUCT_NAME (500): + Localized name of the classification of different Ad + Exchange products. + + Corresponds to "Ad Exchange product" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + AD_EXPERIENCES_TYPE (641): + Ad experiences type. + + Corresponds to "Ad experiences value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + AD_EXPERIENCES_TYPE_NAME (642): + Localized name of the Ad experiences type. + + Corresponds to "Ad experiences" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + AD_LOCATION (390): + Shows an ENUM value describing whether a given piece of + publisher inventory was above (ATF) or below the fold (BTF) + of a page. + + Corresponds to "Ad location value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + AD_LOCATION_NAME (391): + Shows a localized string describing whether a given piece of + publisher inventory was above (ATF) or below the fold (BTF) + of a page. + + Corresponds to "Ad location" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + AD_TECHNOLOGY_PROVIDER_DOMAIN (620): + The domain of the ad technology provider associated with the + bid. + + Corresponds to "Ad technology provider domain" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + AD_TECHNOLOGY_PROVIDER_ID (621): + The ID of the ad technology provider associated with the + bid. + + Corresponds to "Ad technology provider ID" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + AD_TECHNOLOGY_PROVIDER_NAME (622): + The name of the ad technology provider associated with the + bid. + + Corresponds to "Ad technology provider" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + AD_TYPE (497): + Segmentation of ad types. + + Corresponds to "Ad type value" in the Ad Manager UI (when + showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + AD_TYPE_NAME (498): + Localized name of the ad type. + + Corresponds to "Ad type" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + AD_UNIT_CODE (64): + The code of the ad unit where the ad was requested. + + Corresponds to "Ad unit code" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED``, ``REACH`` + + Data format: ``STRING`` + AD_UNIT_CODE_LEVEL_1 (65): + The code of the first level ad unit of the ad unit where the + ad was requested. + + Corresponds to "Ad unit code level 1" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_CODE_LEVEL_10 (74): + The code of the tenth level ad unit of the ad unit where the + ad was requested. + + Corresponds to "Ad unit code level 10" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_CODE_LEVEL_11 (75): + The code of the eleventh level ad unit of the ad unit where + the ad was requested. + + Corresponds to "Ad unit code level 11" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_CODE_LEVEL_12 (76): + The code of the twelfth level ad unit of the ad unit where + the ad was requested. + + Corresponds to "Ad unit code level 12" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_CODE_LEVEL_13 (77): + The code of the thirteenth level ad unit of the ad unit + where the ad was requested. + + Corresponds to "Ad unit code level 13" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_CODE_LEVEL_14 (78): + The code of the fourteenth level ad unit of the ad unit + where the ad was requested. + + Corresponds to "Ad unit code level 14" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_CODE_LEVEL_15 (79): + The code of the fifteenth level ad unit of the ad unit where + the ad was requested. + + Corresponds to "Ad unit code level 15" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_CODE_LEVEL_16 (80): + The code of the sixteenth level ad unit of the ad unit where + the ad was requested. + + Corresponds to "Ad unit code level 16" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_CODE_LEVEL_2 (66): + The code of the second level ad unit of the ad unit where + the ad was requested. + + Corresponds to "Ad unit code level 2" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_CODE_LEVEL_3 (67): + The code of the third level ad unit of the ad unit where the + ad was requested. + + Corresponds to "Ad unit code level 3" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_CODE_LEVEL_4 (68): + The code of the fourth level ad unit of the ad unit where + the ad was requested. + + Corresponds to "Ad unit code level 4" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_CODE_LEVEL_5 (69): + The code of the fifth level ad unit of the ad unit where the + ad was requested. + + Corresponds to "Ad unit code level 5" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_CODE_LEVEL_6 (70): + The code of the sixth level ad unit of the ad unit where the + ad was requested. + + Corresponds to "Ad unit code level 6" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_CODE_LEVEL_7 (71): + The code of the seventh level ad unit of the ad unit where + the ad was requested. + + Corresponds to "Ad unit code level 7" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_CODE_LEVEL_8 (72): + The code of the eighth level ad unit of the ad unit where + the ad was requested. + + Corresponds to "Ad unit code level 8" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_CODE_LEVEL_9 (73): + The code of the ninth level ad unit of the ad unit where the + ad was requested. + + Corresponds to "Ad unit code level 9" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_ID (25): + The ID of the ad unit where the ad was requested. + + Corresponds to "Ad unit ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED``, ``REACH`` + + Data format: ``IDENTIFIER`` + AD_UNIT_ID_ALL_LEVEL (27): + The full hierarchy of ad unit IDs where the ad was + requested, from root to leaf, excluding the root ad unit ID. + + Corresponds to "Ad unit ID (all levels)" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED``, ``REACH`` + + Data format: ``IDENTIFIER_LIST`` + AD_UNIT_ID_LEVEL_1 (30): + The first level ad unit ID of the ad unit where the ad was + requested. + + Corresponds to "Ad unit ID level 1" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + AD_UNIT_ID_LEVEL_10 (48): + The tenth level ad unit ID of the ad unit where the ad was + requested. + + Corresponds to "Ad unit ID level 10" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + AD_UNIT_ID_LEVEL_11 (50): + The eleventh level ad unit ID of the ad unit where the ad + was requested. + + Corresponds to "Ad unit ID level 11" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + AD_UNIT_ID_LEVEL_12 (52): + The twelfth level ad unit ID of the ad unit where the ad was + requested. + + Corresponds to "Ad unit ID level 12" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + AD_UNIT_ID_LEVEL_13 (54): + The thirteenth level ad unit ID of the ad unit where the ad + was requested. + + Corresponds to "Ad unit ID level 13" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + AD_UNIT_ID_LEVEL_14 (56): + The fourteenth level ad unit ID of the ad unit where the ad + was requested. + + Corresponds to "Ad unit ID level 14" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + AD_UNIT_ID_LEVEL_15 (58): + The fifteenth level ad unit ID of the ad unit where the ad + was requested. + + Corresponds to "Ad unit ID level 15" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + AD_UNIT_ID_LEVEL_16 (60): + The sixteenth level ad unit ID of the ad unit where the ad + was requested. + + Corresponds to "Ad unit ID level 16" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + AD_UNIT_ID_LEVEL_2 (32): + The second level ad unit ID of the ad unit where the ad was + requested. + + Corresponds to "Ad unit ID level 2" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + AD_UNIT_ID_LEVEL_3 (34): + The third level ad unit ID of the ad unit where the ad was + requested. + + Corresponds to "Ad unit ID level 3" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + AD_UNIT_ID_LEVEL_4 (36): + The fourth level ad unit ID of the ad unit where the ad was + requested. + + Corresponds to "Ad unit ID level 4" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + AD_UNIT_ID_LEVEL_5 (38): + The fifth level ad unit ID of the ad unit where the ad was + requested. + + Corresponds to "Ad unit ID level 5" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + AD_UNIT_ID_LEVEL_6 (40): + The sixth level ad unit ID of the ad unit where the ad was + requested. + + Corresponds to "Ad unit ID level 6" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + AD_UNIT_ID_LEVEL_7 (42): + The seventh level ad unit ID of the ad unit where the ad was + requested. + + Corresponds to "Ad unit ID level 7" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + AD_UNIT_ID_LEVEL_8 (44): + The eighth level ad unit ID of the ad unit where the ad was + requested. + + Corresponds to "Ad unit ID level 8" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + AD_UNIT_ID_LEVEL_9 (46): + The ninth level ad unit ID of the ad unit where the ad was + requested. + + Corresponds to "Ad unit ID level 9" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + AD_UNIT_ID_TOP_LEVEL (142): + The top-level ad unit ID of the ad unit where the ad was + requested. + + Corresponds to "Ad unit ID (top level)" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + AD_UNIT_NAME (26): + The name of the ad unit where the ad was requested. + + Corresponds to "Ad unit" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED``, ``REACH`` + + Data format: ``STRING`` + AD_UNIT_NAME_ALL_LEVEL (29): + The full hierarchy of ad unit names where the ad was + requested, from root to leaf, excluding the root ad unit + name. + + Corresponds to "Ad unit (all levels)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED``, ``REACH`` + + Data format: ``STRING_LIST`` + AD_UNIT_NAME_LEVEL_1 (31): + The first level ad unit name of the ad unit where the ad was + requested. + + Corresponds to "Ad unit level 1" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_NAME_LEVEL_10 (49): + The tenth level ad unit name of the ad unit where the ad was + requested. + + Corresponds to "Ad unit level 10" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_NAME_LEVEL_11 (51): + The eleventh level ad unit name of the ad unit where the ad + was requested. + + Corresponds to "Ad unit level 11" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_NAME_LEVEL_12 (53): + The twelfth level ad unit name of the ad unit where the ad + was requested. + + Corresponds to "Ad unit level 12" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_NAME_LEVEL_13 (55): + The thirteenth level ad unit name of the ad unit where the + ad was requested. + + Corresponds to "Ad unit level 13" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_NAME_LEVEL_14 (57): + The fourteenth level ad unit name of the ad unit where the + ad was requested. + + Corresponds to "Ad unit level 14" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_NAME_LEVEL_15 (59): + The fifteenth level ad unit name of the ad unit where the ad + was requested. + + Corresponds to "Ad unit level 15" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_NAME_LEVEL_16 (61): + The sixteenth level ad unit name of the ad unit where the ad + was requested. + + Corresponds to "Ad unit level 16" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_NAME_LEVEL_2 (33): + The second level ad unit name of the ad unit where the ad + was requested. + + Corresponds to "Ad unit level 2" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_NAME_LEVEL_3 (35): + The third level ad unit name of the ad unit where the ad was + requested. + + Corresponds to "Ad unit level 3" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_NAME_LEVEL_4 (37): + The fourth level ad unit name of the ad unit where the ad + was requested. + + Corresponds to "Ad unit level 4" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_NAME_LEVEL_5 (39): + The fifth level ad unit name of the ad unit where the ad was + requested. + + Corresponds to "Ad unit level 5" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_NAME_LEVEL_6 (41): + The sixth level ad unit name of the ad unit where the ad was + requested. + + Corresponds to "Ad unit level 6" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_NAME_LEVEL_7 (43): + The seventh level ad unit name of the ad unit where the ad + was requested. + + Corresponds to "Ad unit level 7" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_NAME_LEVEL_8 (45): + The eighth level ad unit name of the ad unit where the ad + was requested. + + Corresponds to "Ad unit level 8" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_NAME_LEVEL_9 (47): + The ninth level ad unit name of the ad unit where the ad was + requested. + + Corresponds to "Ad unit level 9" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_NAME_TOP_LEVEL (143): + The top-level ad unit name of the ad unit where the ad was + requested. + + Corresponds to "Ad unit (top level)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AD_UNIT_REWARD_AMOUNT (63): + The reward amount of the ad unit where the ad was requested. + + Corresponds to "Ad unit reward amount" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED``, ``REACH`` + + Data format: ``INTEGER`` + AD_UNIT_REWARD_TYPE (62): + The reward type of the ad unit where the ad was requested. + + Corresponds to "Ad unit reward type" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED``, ``REACH`` + + Data format: ``STRING`` + AD_UNIT_STATUS (206): + The status of the ad unit + + Corresponds to "Ad unit status value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``ENUM`` + AD_UNIT_STATUS_NAME (207): + The name of the status of the ad unit + + Corresponds to "Ad unit status" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + AGENCY_LEVEL_1_ID (565): + The ID of an agency at level 1 of agency hierarchy. + + Corresponds to "Agency ID (Level 1)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + AGENCY_LEVEL_1_NAME (566): + The name of an agency at level 1 of agency hierarchy. + + Corresponds to "Agency (Level 1)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + AGENCY_LEVEL_2_ID (567): + The ID of an agency at level 2 of agency hierarchy. + + Corresponds to "Agency ID (Level 2)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + AGENCY_LEVEL_2_NAME (568): + The name of an agency at level 2 of agency hierarchy. + + Corresponds to "Agency (Level 2)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + AGENCY_LEVEL_3_ID (569): + The ID of an agency at level 3 of agency hierarchy. + + Corresponds to "Agency ID (Level 3)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + AGENCY_LEVEL_3_NAME (570): + The name of an agency at level 3 of agency hierarchy. + + Corresponds to "Agency (Level 3)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + AGE_BRACKET (508): + User age bracket enum. + + Corresponds to "Age bracket value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + AGE_BRACKET_NAME (582): + Localized user age bracket returned from Google Analytics. + For example, "18-24", "25-34", "35-44", "45-54", "55-64", + "65+". + + Corresponds to "Age bracket" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + APP_TRACKING_TRANSPARENCY_CONSENT_STATUS (442): + Enum value for App Tracking Transparency consent status. + + Corresponds to "App Tracking Transparency consent status + value" in the Ad Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + APP_TRACKING_TRANSPARENCY_CONSENT_STATUS_NAME (443): + Localized string value for App Tracking Transparency consent + status. + + Corresponds to "App Tracking Transparency consent status" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + APP_VERSION (392): + The app version. + + Corresponds to "App version" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + AUCTION_PACKAGE_DEAL (579): + The name of Auction Package deal + + Corresponds to "Auction package deal" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + AUCTION_PACKAGE_DEAL_ID (571): + The ID of Auction Package deal + + Corresponds to "Auction package deal ID" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + AUDIENCE_SEGMENT_ID_TARGETED (584): + ID of targeted audience segment, including all first-party + and third-party segments that matched the user on the + winning line item. + + Corresponds to "Audience segment ID (targeted)" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + AUDIENCE_SEGMENT_TARGETED (585): + Name of targeted audience segment, including all first-party + and third-party segments that matched the user on the + winning line item. + + Corresponds to "Audience segment (targeted)" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + AUTO_REFRESHED_TRAFFIC (421): + Enum value of Auto refreshed traffic. + + Corresponds to "Auto refreshed traffic value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + AUTO_REFRESHED_TRAFFIC_NAME (422): + Indicates if the traffic is from auto-refreshed ad requests. + + Corresponds to "Auto refreshed traffic" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + BIDDER_ENCRYPTED_ID (493): + The encrypted version of BIDDER_ID. + + Corresponds to "Bidder encrypted ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + BIDDER_NAME (494): + The name of the bidder. + + Corresponds to "Bidder" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + BID_RANGE (679): + The cpm range within which a bid falls. + + Corresponds to "Bid Range" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``BID_RANGE`` + BID_REJECTION_REASON (599): + The reason a bid was rejected. + + Corresponds to "Bid rejection reason value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + BID_REJECTION_REASON_NAME (600): + The localized name of the reason a bid was rejected. + + Corresponds to "Bid rejection reason" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + BRANDING_TYPE (383): + The amount of information about the Publisher's page sent to + the buyer who purchased the impressions. + + Corresponds to "Branding type value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + BRANDING_TYPE_NAME (384): + The localized version of branding type, the amount of + information about the Publisher's page sent to the buyer who + purchased the impressions. + + Corresponds to "Branding type" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + BROWSER_CATEGORY (119): + Browser category. + + Corresponds to "Browser category value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``ENUM`` + BROWSER_CATEGORY_NAME (120): + Browser category name. + + Corresponds to "Browser category" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + BROWSER_ID (235): + The ID of the browser. + + Corresponds to "Browser ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + BROWSER_NAME (236): + The name of the browser. + + Corresponds to "Browser" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + BUYER_NETWORK_ID (448): + The ID of the buyer network. + + Corresponds to "Buyer network ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + BUYER_NETWORK_NAME (449): + The name of the buyer network. + + Corresponds to "Buyer network" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + CALLOUT_STATUS_CATEGORY (588): + The callout status category in the Ads traffic navigator + report. + + Corresponds to "Callout status category value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: + + Data format: ``ENUM`` + CALLOUT_STATUS_CATEGORY_NAME (589): + The callout status category name in the Ads traffic + navigator report. + + Corresponds to "Callout status category" in the Ad Manager + UI. + + Compatible with the following report types: + + Data format: ``STRING`` + CARRIER_ID (369): + Mobile carrier ID. + + Corresponds to "Carrier ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + CARRIER_NAME (368): + Name of the mobile carrier. + + Corresponds to "Carrier" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + CHANNEL (501): + Inventory segmentation by channel. + + Corresponds to "Channel" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + CHILD_NETWORK_CODE (542): + Child Publisher Network Code + + Corresponds to "Child network code" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + CHILD_NETWORK_ID (544): + Child Publisher Network ID + + Corresponds to "Child network ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + CHILD_PARTNER_NAME (543): + Child Partner Network Name + + Corresponds to "Child network" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + CITY_ID (459): + The criteria ID of the city in which the ad served. + + Corresponds to "City ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + CITY_NAME (452): + The name of the city in which the ad served. + + Corresponds to "City" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + CLASSIFIED_ADVERTISER_ID (133): + The ID of an advertiser, classified by Google, associated + with a creative transacted + + Corresponds to "Advertiser ID (classified)" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + CLASSIFIED_ADVERTISER_NAME (134): + The name of an advertiser, classified by Google, associated + with a creative transacted + + Corresponds to "Advertiser (classified)" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + CLASSIFIED_BRAND_ID (243): + ID of the brand, as classified by Google, + + Corresponds to "Brand ID (classified)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + CLASSIFIED_BRAND_NAME (244): + Name of the brand, as classified by Google, + + Corresponds to "Brand (classified)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + CONTENT_CMS_NAME (643): + The display name of the CMS content. + + Corresponds to "Content source name" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + CONTENT_CMS_VIDEO_ID (644): + The CMS content ID of the video content. + + Corresponds to "ID of the video in the content source" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + CONTENT_ID (246): + ID of the video content served. + + Corresponds to "Content ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + CONTENT_MAPPING_PRESENCE (731): + Content mapping presence ENUM value + + Corresponds to "Content mapping presence value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + CONTENT_MAPPING_PRESENCE_NAME (732): + Content mapping presence name + + Corresponds to "Content mapping presence" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + CONTENT_NAME (247): + Name of the video content served. + + Corresponds to "Content" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + CONTINENT (469): + The continent in which the ad served (derived from country). + + Corresponds to "Continent value" in the Ad Manager UI (when + showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + CONTINENT_NAME (470): + The name of the continent in which the ad served (derived + from country). + + Corresponds to "Continent" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + COUNTRY_CODE (466): + The ISO code of the country in which the ad served. + + Corresponds to "Country code" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``PRIVACY_AND_MESSAGING``, ``AD_SPEED`` + + Data format: ``STRING`` + COUNTRY_ID (11): + The criteria ID of the country in which the ad served. + + Corresponds to "Country ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``PRIVACY_AND_MESSAGING``, ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + COUNTRY_NAME (12): + The name of the country in which the ad served. + + Corresponds to "Country" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``PRIVACY_AND_MESSAGING``, ``AD_SPEED`` + + Data format: ``STRING`` + CREATIVE_BILLING_TYPE (366): + Enum value of creative billing type + + Corresponds to "Creative billing type value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + CREATIVE_BILLING_TYPE_NAME (367): + Localized string value of creative billing type + + Corresponds to "Creative billing type" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + CREATIVE_CLICK_THROUGH_URL (174): + Represents the click-through URL of a creative + + Corresponds to "Creative click through url" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + CREATIVE_ID (138): + The ID of a creative + + Corresponds to "Creative ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + CREATIVE_NAME (139): + Creative name + + Corresponds to "Creative" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + CREATIVE_POLICIES_FILTERING (711): + Creative Policies filtering. + + Corresponds to "Creative policies filtering value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + CREATIVE_POLICIES_FILTERING_NAME (712): + Localized name of the Creative Policies filtering. + + Corresponds to "Creative policies filtering" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + CREATIVE_PROTECTIONS_FILTERING (704): + Creative Protections filtering (Publisher Blocks + Enforcement). + + Corresponds to "Creative protections filtering value" in the + Ad Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + CREATIVE_PROTECTIONS_FILTERING_NAME (705): + Localized name of the Creative Protections filtering. + + Corresponds to "Creative protections filtering" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + CREATIVE_SET_ROLE_TYPE (686): + ENUM describing whether the creative is part of a creative + set and if so, what its role in the creative set is. + + Corresponds to "Creative set role type value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + CREATIVE_SET_ROLE_TYPE_NAME (687): + Localized name describing whether the creative is part of a + creative set and if so, what its role in the creative set + is. + + Corresponds to "Creative set role type" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + CREATIVE_TECHNOLOGY (148): + Creative technology ENUM + + Corresponds to "Creative technology value" in the Ad Manager + UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + CREATIVE_TECHNOLOGY_NAME (149): + Creative technology locallized name + + Corresponds to "Creative technology" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + CREATIVE_THIRD_PARTY_VENDOR (361): + Third party vendor name of a creative + + Corresponds to "Creative third party vendor" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + CREATIVE_TYPE (344): + Enum value of creative type + + Corresponds to "Creative type value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``ENUM`` + CREATIVE_TYPE_NAME (345): + Localized string name of creative type + + Corresponds to "Creative type" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + CREATIVE_VENDOR_ID (706): + Creative vendor ID. + + Corresponds to "Creative vendor ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + CREATIVE_VENDOR_NAME (707): + Name of the Creative vendor. + + Corresponds to "Creative vendor" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + CREATIVE_VIDEO_REDIRECT_THIRD_PARTY (562): + The third party where Google Ad Manager was redirected for + the creative, based on the domain. + + Corresponds to "Creative video redirect third party" in the + Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + CURATOR_ID (572): + The ID of a Curation partner + + Corresponds to "Curation partner ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + CURATOR_NAME (573): + The name of a Curation partner + + Corresponds to "Curation partner" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + CUSTOM_EVENT_ID (737): + Custom event ID + + Corresponds to "Custom event id" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + CUSTOM_EVENT_NAME (735): + Custom event name + + Corresponds to "Custom event" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + CUSTOM_EVENT_TYPE (736): + Custom event type + + Corresponds to "Custom event type value" in the Ad Manager + UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + CUSTOM_EVENT_TYPE_NAME (738): + Localized name of the custom event type + + Corresponds to "Custom event type" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + CUSTOM_SPOT_ID (423): + The ID of an ad spot. An ad spot can be added to an ad break + template, as well as directly targeted by a video line item. + + Corresponds to "Custom spot ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + CUSTOM_SPOT_NAME (424): + The name of an ad spot. An ad spot can be added to an ad + break template, as well as directly targeted by a video line + item. + + Corresponds to "Custom spot" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + DATE (3): + Breaks down reporting data by date. + + Corresponds to "Date" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``PRIVACY_AND_MESSAGING``, ``AD_SPEED`` + + Data format: ``DATE`` + DAY_OF_WEEK (4): + Breaks down reporting data by day of the week. Monday is 1 + and 7 is Sunday. + + Corresponds to "Day of week" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``PRIVACY_AND_MESSAGING`` + + Data format: ``INTEGER`` + DEAL_BUYER_ID (240): + The ID of the buyer of a deal. + + Corresponds to "Deal buyer ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + DEAL_BUYER_NAME (241): + The name of the buyer of a deal. + + Corresponds to "Deal buyer" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + DEAL_ID (436): + Deal ID + + Corresponds to "Deal ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + DEAL_NAME (437): + Deal name + + Corresponds to "Deal" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + DELIVERED_SECURE_SIGNAL_ID (309): + The ID of the secure signals that were sent to the bidder + who won the impression. + + Corresponds to "Secure signal ID (delivered)" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + DELIVERED_SECURE_SIGNAL_NAME (310): + The name of the secure signals that were sent to the bidder + who won the impression. + + Corresponds to "Secure signal name (delivered)" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + DEMAND_CHANNEL (9): + Demand channel. + + Corresponds to "Demand channel value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``ENUM`` + DEMAND_CHANNEL_NAME (10): + Demand channel name. + + Corresponds to "Demand channel" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``STRING`` + DEMAND_SOURCE (592): + Demand source. + + Corresponds to "Demand source value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: + + Data format: ``ENUM`` + DEMAND_SOURCE_NAME (593): + Demand source name. + + Corresponds to "Demand source" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``STRING`` + DEMAND_SUBCHANNEL (22): + Demand subchannel. + + Corresponds to "Demand subchannel value" in the Ad Manager + UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + DEMAND_SUBCHANNEL_NAME (23): + Demand subchannel name. + + Corresponds to "Demand subchannel" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + DEVICE (226): + The device on which an ad was served. + + Corresponds to "Device value" in the Ad Manager UI (when + showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + DEVICE_CATEGORY (15): + The device category to which an ad is being targeted. + + Corresponds to "Device category value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL``, + ``PRIVACY_AND_MESSAGING``, ``AD_SPEED`` + + Data format: ``ENUM`` + DEVICE_CATEGORY_NAME (16): + The name of the category of device (smartphone, feature + phone, tablet, or desktop) to which an ad is being targeted. + + Corresponds to "Device category" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``PRIVACY_AND_MESSAGING``, ``AD_SPEED`` + + Data format: ``STRING`` + DEVICE_MANUFACTURER_ID (525): + Device manufacturer ID + + Corresponds to "Device manufacturer ID" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + DEVICE_MANUFACTURER_NAME (526): + Device manufacturer name + + Corresponds to "Device manufacturer" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + DEVICE_MODEL_ID (527): + Device model ID + + Corresponds to "Device model ID" in the Ad Manager UI (when + showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + DEVICE_MODEL_NAME (528): + Device model name + + Corresponds to "Device model" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + DEVICE_NAME (225): + The localized name of the device on which an ad was served. + + Corresponds to "Device" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + DSP_SEAT_ID (564): + The ID of DSP Seat + + Corresponds to "DSP seat ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + DYNAMIC_ALLOCATION_TYPE (502): + Categorization of inventory sources based on AdX dynamic + allocation backfill type. + + Corresponds to "Dynamic allocation value" in the Ad Manager + UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + DYNAMIC_ALLOCATION_TYPE_NAME (503): + Localized name of the dynamic allocation type. + + Corresponds to "Dynamic allocation" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + ESP_DELIVERY (623): + Status of Encrypted Signals for Publishers delivery. + + Corresponds to "Secure signal delivery value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + ESP_DELIVERY_NAME (624): + Localized name of the ESP delivery status. + + Corresponds to "Secure signal delivery" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + ESP_PRESENCE (625): + Whether Encrypted Signals for Publishers are present on the + ad request. + + Corresponds to "Secure signal presence value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + ESP_PRESENCE_NAME (626): + Localized name of the ESP presence status. + + Corresponds to "Secure signal presence" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + EXCHANGE_BIDDING_DEAL_ID (715): + Exchange bidding deal ID. + + Corresponds to "Exchange bidding deal id" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + EXCHANGE_BIDDING_DEAL_TYPE (714): + Exchange bidding deal type. + + Corresponds to "Exchange bidding deal type value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + EXCHANGE_BIDDING_DEAL_TYPE_NAME (723): + Localized name of the exchange bidding deal type. + + Corresponds to "Exchange bidding deal type" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + EXCHANGE_THIRD_PARTY_COMPANY_ID (185): + ID of the yield partner as classified by Google + + Corresponds to "Yield partner ID (classified)" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + EXCHANGE_THIRD_PARTY_COMPANY_NAME (186): + Name of the yield partner as classified by Google + + Corresponds to "Yield partner (classified)" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + FIRST_LOOK_PRICING_RULE_ID (248): + The ID of the first look pricing rule. + + Corresponds to "First look pricing rule ID" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + FIRST_LOOK_PRICING_RULE_NAME (249): + The name of the first look pricing rule. + + Corresponds to "First look pricing rule" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + FIRST_PARTY_ID_STATUS (404): + Whether a first-party user identifier was present on a given + ad-request. + + Corresponds to "First-party ID status value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + FIRST_PARTY_ID_STATUS_NAME (405): + The localized name of whether a first-party user identifier + was present on a given ad-request. + + Corresponds to "First-party ID status" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + GENDER (509): + User gender enum value returned from Google Analytics. + + Corresponds to "Gender value" in the Ad Manager UI (when + showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + GENDER_NAME (583): + Localized user gender returned from Google Analytics. For + example, "male", "female". + + Corresponds to "Gender" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + GOOGLE_ANALYTICS_STREAM_ID (519): + The ID of a Google Analytics stream. For example, web site + or mobile app + + Corresponds to "Google Analytics stream ID" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + GOOGLE_ANALYTICS_STREAM_NAME (520): + The name of a Google Analytics stream. For example, web site + or mobile app. + + Corresponds to "Google Analytics stream" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + HBT_YIELD_PARTNER_ID (659): + The ID of the header bidding trafficking yield partner. + + Corresponds to "Yield partner ID (header bidding + trafficking)" in the Ad Manager UI (when showing API + fields). + + Compatible with the following report types: + + Data format: ``IDENTIFIER`` + HBT_YIELD_PARTNER_NAME (660): + The name of the header bidding trafficking yield partner. + + Corresponds to "Yield partner (header bidding trafficking)" + in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``STRING`` + HEADER_BIDDER_INTEGRATION_TYPE (718): + Header Bidder integration type. + + Corresponds to "Header bidder integration type value" in the + Ad Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + HEADER_BIDDER_INTEGRATION_TYPE_NAME (719): + Localized name of the Header Bidder integration type. + + Corresponds to "Header bidder integration type" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + HOUR (100): + Breaks down reporting data by hour in one day. + + Corresponds to "Hour" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + IMPRESSION_COUNTING_METHOD (577): + Impression Counting Method ENUM. + + Corresponds to "Impression counting method value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + IMPRESSION_COUNTING_METHOD_NAME (578): + Localized impression counting method name. + + Corresponds to "Impression counting method" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + INTERACTION_TYPE (223): + The interaction type of an ad. + + Corresponds to "Interaction type value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + INTERACTION_TYPE_NAME (224): + The localized name of the interaction type of an ad. + + Corresponds to "Interaction type" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + INTEREST (510): + User interest returned from Google Analytics. + + Corresponds to "Interests" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + INVENTORY_FORMAT (17): + Inventory format. The format of the ad unit (e.g, banner) + where the ad was requested. + + Corresponds to "Inventory format value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + INVENTORY_FORMAT_NAME (18): + Inventory format name. The format of the ad unit (e.g, + banner) where the ad was requested. + + Corresponds to "Inventory format" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + INVENTORY_SHARE_ASSIGNMENT_ID (648): + The ID of the inventory share assignment. + + Corresponds to "Inventory share assignment ID" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + INVENTORY_SHARE_ASSIGNMENT_NAME (649): + The name of the inventory share assignment. + + Corresponds to "Inventory share assignment" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + INVENTORY_SHARE_OUTCOME (603): + The result of an inventory share. + + Corresponds to "Inventory share outcome value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + INVENTORY_SHARE_OUTCOME_NAME (604): + The localized name of the result of an inventory share. + + Corresponds to "Inventory share outcome" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + INVENTORY_SHARE_PARTNER_AD_SERVER (652): + The partner ad server of the inventory share. + + Corresponds to "Inventory share partner ad server value" in + the Ad Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + INVENTORY_SHARE_PARTNER_AD_SERVER_NAME (653): + The localized name of the partner ad server. + + Corresponds to "Inventory share partner ad server" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + INVENTORY_SHARE_TARGET_SHARE_PERCENT (654): + The target share percent of the inventory share assignment + + Corresponds to "Partner target share percent" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + INVENTORY_SHARE_TYPE (650): + The type of the inventory share. + + Corresponds to "Inventory share type value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + INVENTORY_SHARE_TYPE_NAME (651): + The localized name of the inventory share type. + + Corresponds to "Inventory share type" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + INVENTORY_TYPE (19): + Inventory type. The kind of web page or device where the ad + was requested. + + Corresponds to "Inventory type (expanded) value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + INVENTORY_TYPE_NAME (20): + Inventory type name. The kind of web page or device where + the ad was requested. + + Corresponds to "Inventory type (expanded)" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + IS_ADX_DIRECT (382): + Whether traffic is Adx Direct. + + Corresponds to "Is AdX Direct" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``BOOLEAN`` + IS_CURATION_TARGETED (574): + If curation was targeted by the buyer when buying the + impression + + Corresponds to "Is curation targeted" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``BOOLEAN`` + IS_DROPPED (464): + Whether the query was dropped. + + Corresponds to "Is Dropped" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``BOOLEAN`` + IS_FIRST_LOOK_DEAL (401): + Whether traffic is First Look. + + Corresponds to "Is First Look" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``BOOLEAN`` + KEY_VALUES_ID (214): + The Custom Targeting Value ID + + Corresponds to "Key-values ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + KEY_VALUES_NAME (215): + The Custom Targeting Value formatted like + ``{keyName}={valueName}`` + + Corresponds to "Key-values" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + LINE_ITEM_AGENCY (663): + The agency of the order associated with the line item. + + Corresponds to "Line item agency" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + LINE_ITEM_ARCHIVED (188): + Whether a Line item is archived. + + Corresponds to "Line item is archived" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``BOOLEAN`` + LINE_ITEM_COMPANION_DELIVERY_OPTION (204): + Line item comanion delivery option ENUM value. + + Corresponds to "Line item companion delivery option value" + in the Ad Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``ENUM`` + LINE_ITEM_COMPANION_DELIVERY_OPTION_NAME (205): + Localized line item comanion delivery option name. + + Corresponds to "Line item companion delivery option" in the + Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + LINE_ITEM_COMPUTED_STATUS (250): + The computed status of the LineItem. + + Corresponds to "Line item computed status value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``ENUM`` + LINE_ITEM_COMPUTED_STATUS_NAME (251): + The localized name of the computed status of the LineItem. + + Corresponds to "Line item computed status" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``STRING`` + LINE_ITEM_CONTRACTED_QUANTITY (92): + The contracted units bought for the Line item. + + Corresponds to "Line item contracted quantity" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``INTEGER`` + LINE_ITEM_COST_PER_UNIT (85): + The cost per unit of the Line item. + + Corresponds to "Line item rate" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``MONEY`` + LINE_ITEM_COST_TYPE (212): + Line item cost type ENUM value. + + Corresponds to "Line item cost type value" in the Ad Manager + UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``ENUM`` + LINE_ITEM_COST_TYPE_NAME (213): + Localized line item cost type name. + + Corresponds to "Line item cost type" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``STRING`` + LINE_ITEM_CREATIVE_END_DATE (176): + Represent the end date of a creative associated with line + item + + Corresponds to "Line item creative end date" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DATE`` + LINE_ITEM_CREATIVE_ROTATION_TYPE (189): + The creative rotation type of the LineItem. + + Corresponds to "Line item creative rotation type value" in + the Ad Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``ENUM`` + LINE_ITEM_CREATIVE_ROTATION_TYPE_NAME (190): + The localized name of the creative rotation type of the + LineItem. + + Corresponds to "Line item creative rotation type" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + LINE_ITEM_CREATIVE_START_DATE (175): + Represent the start date of a creative associated with line + item + + Corresponds to "Line item creative start date" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DATE`` + LINE_ITEM_CURRENCY_CODE (180): + The 3 letter currency code of the Line Item + + Corresponds to "Line item currency code" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``STRING`` + LINE_ITEM_DELIVERY_INDICATOR (87): + The progress made for the delivery of the Line item. + + Corresponds to "Line item delivery indicator" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``PERCENT`` + LINE_ITEM_DELIVERY_RATE_TYPE (191): + The delivery rate type of the LineItem. + + Corresponds to "Line item delivery rate type value" in the + Ad Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``ENUM`` + LINE_ITEM_DELIVERY_RATE_TYPE_NAME (192): + The localized name of the delivery rate type of the + LineItem. + + Corresponds to "Line item delivery rate type" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``STRING`` + LINE_ITEM_DISCOUNT_ABSOLUTE (195): + The discount of the LineItem in whole units in the + LineItem's currency code, or if unspecified the Network's + currency code. + + Corresponds to "Line item discount (absolute)" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``MONEY`` + LINE_ITEM_DISCOUNT_PERCENTAGE (196): + The discount of the LineItem in percentage. + + Corresponds to "Line item discount (percentage)" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``WHOLE_PERCENT`` + LINE_ITEM_END_DATE (81): + The end date of the Line item. + + Corresponds to "Line item end date" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``DATE`` + LINE_ITEM_END_DATE_TIME (83): + The end date and time of the Line item. + + Corresponds to "Line item end time" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``TIMESTAMP`` + LINE_ITEM_ENVIRONMENT_TYPE (201): + The ENUM value of the environment a LineItem is targeting. + + Corresponds to "Line item environment type value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``ENUM`` + LINE_ITEM_ENVIRONMENT_TYPE_NAME (202): + The localized name of the environment a LineItem is + targeting. + + Corresponds to "Line item environment type" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + LINE_ITEM_EXTERNAL_DEAL_ID (97): + The deal ID of the Line item. Set for Programmatic Direct + campaigns. + + Corresponds to "Line item deal ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``IDENTIFIER`` + LINE_ITEM_EXTERNAL_ID (86): + The external ID of the Line item. + + Corresponds to "Line item external ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + LINE_ITEM_FREQUENCY_CAP (256): + The frequency cap of the Line item (descriptive string). + + Corresponds to "Line item frequency cap" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + LINE_ITEM_ID (1): + Line item ID. + + Corresponds to "Line item ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + LINE_ITEM_LABELS (667): + Line item labels. + + Corresponds to "Line item labels" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING_LIST`` + LINE_ITEM_LABEL_IDS (665): + Line item label IDs. + + Corresponds to "Line item label IDs" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``IDENTIFIER_LIST`` + LINE_ITEM_LAST_MODIFIED_BY_APP (181): + The application that last modified the Line Item. + + Corresponds to "Line item last modified by app" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + LINE_ITEM_LIFETIME_CLICKS (95): + The total number of clicks delivered of the lifetime of the + Line item. + + Corresponds to "Line item lifetime clicks" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``INTEGER`` + LINE_ITEM_LIFETIME_IMPRESSIONS (94): + The total number of impressions delivered over the lifetime + of the Line item. + + Corresponds to "Line item lifetime impressions" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``INTEGER`` + LINE_ITEM_LIFETIME_VIEWABLE_IMPRESSIONS (96): + The total number of viewable impressions delivered over the + lifetime of the Line item. + + Corresponds to "Line item lifetime viewable impressions" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``INTEGER`` + LINE_ITEM_MAKEGOOD (89): + Whether or not the Line item is Makegood. Makegood refers to + free inventory offered to buyers to compensate for mistakes + or under-delivery in the original campaigns. + + Corresponds to "Line item is makegood" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``BOOLEAN`` + LINE_ITEM_NAME (2): + Line item Name. + + Corresponds to "Line item" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``STRING`` + LINE_ITEM_NON_CPD_BOOKED_REVENUE (98): + The cost of booking for the Line item (non-CPD). + + Corresponds to "Line item booked revenue (exclude CPD)" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``MONEY`` + LINE_ITEM_OPTIMIZABLE (90): + Whether a Line item is eligible for opitimization. + + Corresponds to "Line item is optimizable" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``BOOLEAN`` + LINE_ITEM_PO_NUMBER (669): + The PO number of the order associated with the line item. + + Corresponds to "Line item PO number" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``STRING`` + LINE_ITEM_PRIMARY_GOAL_TYPE (210): + Goal type ENUM value of the primary goal of the line item. + + Corresponds to "Line item primary goal type value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``ENUM`` + LINE_ITEM_PRIMARY_GOAL_TYPE_NAME (211): + Localized goal type name of the primary goal of the line + item. + + Corresponds to "Line item primary goal type" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + LINE_ITEM_PRIMARY_GOAL_UNITS_ABSOLUTE (93): + The total number of impressions or clicks that are reserved + for a line item. For line items of type BULK or + PRICE_PRIORITY, this represents the number of remaining + impressions reserved. If the line item has an impression cap + goal, this represents the number of impressions or + conversions that the line item will stop serving at if + reached. + + Corresponds to "Line item primary goal units (absolute)" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``INTEGER`` + LINE_ITEM_PRIMARY_GOAL_UNITS_PERCENTAGE (396): + The percentage of impressions or clicks that are reserved + for a line item. For line items of type SPONSORSHIP, this + represents the percentage of available impressions reserved. + For line items of type NETWORK or HOUSE, this represents the + percentage of remaining impressions reserved. + + Corresponds to "Line item primary goal units (percentage)" + in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``WHOLE_PERCENT`` + LINE_ITEM_PRIMARY_GOAL_UNIT_TYPE (208): + Unit type ENUM value of the primary goal of the line item. + + Corresponds to "Line item primary goal unit type value" in + the Ad Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``ENUM`` + LINE_ITEM_PRIMARY_GOAL_UNIT_TYPE_NAME (209): + Localized unit type name of the primary goal of the line + item. + + Corresponds to "Line item primary goal unit type" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + LINE_ITEM_PRIORITY (24): + The priority of this Line item as a value between 1 and 16. + In general, a lower priority means more serving priority for + the Line item. + + Corresponds to "Line item priority" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``INTEGER`` + LINE_ITEM_RESERVATION_STATUS (304): + ENUM value describing the state of inventory reservation for + the LineItem. + + Corresponds to "Line item reservation status value" in the + Ad Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``ENUM`` + LINE_ITEM_RESERVATION_STATUS_NAME (305): + Localized string describing the state of inventory + reservation for the LineItem. + + Corresponds to "Line item reservation status" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + LINE_ITEM_SALESPERSON (671): + The sales person of the order associated with the line item. + + Corresponds to "Line item salesperson" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + LINE_ITEM_SECONDARY_SALESPEOPLE (673): + The secondary sales people of the order associated with the + line item. + + Corresponds to "Line item secondary salespeople" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING_LIST`` + LINE_ITEM_SECONDARY_TRAFFICKERS (675): + The secondary traffickers of the order associated with the + line item. + + Corresponds to "Line item secondary traffickers" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING_LIST`` + LINE_ITEM_START_DATE (82): + The start date of the Line item. + + Corresponds to "Line item start date" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``DATE`` + LINE_ITEM_START_DATE_TIME (84): + The start date and time of the Line item. + + Corresponds to "Line item start time" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``TIMESTAMP`` + LINE_ITEM_TRAFFICKER (677): + The trafficker of the order associated with the line item. + + Corresponds to "Line item trafficker" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + LINE_ITEM_TYPE (193): + Line item type ENUM value. + + Corresponds to "Line item type value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``ENUM`` + LINE_ITEM_TYPE_NAME (194): + Localized line item type name. + + Corresponds to "Line item type" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``STRING`` + LINE_ITEM_UNLIMITED_END (187): + Whether the Line item end time and end date is set to + effectively never end. + + Corresponds to "Line item is unlimited end time" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``BOOLEAN`` + LINE_ITEM_VALUE_COST_PER_UNIT (88): + The artificial cost per unit used by the Ad server to help + rank inventory. + + Corresponds to "Line item value cost per unit" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``MONEY`` + LINE_ITEM_WEB_PROPERTY_CODE (179): + The web property code used for dynamic allocation Line + Items. + + Corresponds to "Line item web property code" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + MASTER_COMPANION_CREATIVE_ID (140): + The ID of creative, includes regular creatives, and master + and companions in case of creative sets + + Corresponds to "Master and Companion creative ID" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + MASTER_COMPANION_CREATIVE_NAME (141): + Name of creative, includes regular creatives, and master and + companions in case of creative sets + + Corresponds to "Master and Companion creative" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + MEDIATION_TYPE (701): + Mediation type. + + Corresponds to "Mediation type value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + MEDIATION_TYPE_NAME (754): + Localized mediation type name. + + Corresponds to "Mediation type" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + MEDIATION_YIELD_PARTNER_ID (661): + The ID of the yield partner for Mediation. + + Corresponds to "Yield partner ID (mediation)" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: + + Data format: ``IDENTIFIER`` + MEDIATION_YIELD_PARTNER_NAME (662): + The name of the yield partner for Mediation. + + Corresponds to "Yield partner (mediation)" in the Ad Manager + UI. + + Compatible with the following report types: + + Data format: ``STRING`` + METRO_ID (453): + The criteria ID of the metro area in which the ad served. + + Corresponds to "Metro ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + METRO_NAME (454): + The name of the metro area in which the ad served. + + Corresponds to "Metro" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + MOBILE_APP_FREE (128): + Whether the mobile app is free. + + Corresponds to "App is free" in the Ad Manager UI (when + showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``BOOLEAN`` + MOBILE_APP_ICON_URL (129): + URL of app icon for the mobile app. + + Corresponds to "App icon URL" in the Ad Manager UI (when + showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + MOBILE_APP_ID (123): + The ID of the Mobile App. + + Corresponds to "App ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``PRIVACY_AND_MESSAGING`` + + Data format: ``STRING`` + MOBILE_APP_NAME (127): + The name of the mobile app. + + Corresponds to "App" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``PRIVACY_AND_MESSAGING`` + + Data format: ``STRING`` + MOBILE_APP_OWNERSHIP_STATUS (311): + Ownership status of the mobile app. + + Corresponds to "App ownership status value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + MOBILE_APP_OWNERSHIP_STATUS_NAME (312): + Ownership status of the mobile app. + + Corresponds to "App ownership status" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + MOBILE_APP_STORE (125): + The App Store of the mobile app. + + Corresponds to "App store value" in the Ad Manager UI (when + showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + MOBILE_APP_STORE_NAME (245): + The localized name of the mobile app store. + + Corresponds to "App store" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + MOBILE_INVENTORY_TYPE (99): + Mobile inventory type. Identifies whether a mobile ad came + from a regular web page, an AMP web page, or a mobile app. + Values match the Inventory type dimension available in the + Overview Home dashboard. Note: Video takes precedence over + any other value, for example, if there is an in-stream video + impression on a desktop device, it will be attributed to + in-stream video and not desktop web. + + Corresponds to "Inventory type value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL``, + ``PRIVACY_AND_MESSAGING``, ``AD_SPEED`` + + Data format: ``ENUM`` + MOBILE_INVENTORY_TYPE_NAME (21): + Mobile inventory type name. Identifies whether a mobile ad + came from a regular web page, an AMP web page, or a mobile + app. + + Corresponds to "Inventory type" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``PRIVACY_AND_MESSAGING``, ``AD_SPEED`` + + Data format: ``STRING`` + MOBILE_RENDERING_SDK (646): + Mobile rendering SDK. + + Corresponds to "Rendering SDK value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + MOBILE_RENDERING_SDK_NAME (647): + Localized name of the Mobile rendering SDK. + + Corresponds to "Rendering SDK" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + MOBILE_SDK_MAJOR_VERSION (692): + The major version of the mobile SDK. + + Corresponds to "App SDK major version" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + MOBILE_SDK_MINOR_VERSION (693): + The minor version of the mobile SDK. + + Corresponds to "App SDK minor version" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + MOBILE_SDK_VERSION_NAME (130): + SDK version of the mobile device. + + Corresponds to "App SDK version" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + MONTH_YEAR (6): + Breaks down reporting data by month and year. + + Corresponds to "Month and year" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``PRIVACY_AND_MESSAGING`` + + Data format: ``INTEGER`` + NATIVE_AD_FORMAT_ID (255): + Native ad format ID. + + Corresponds to "Native ad format ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + NATIVE_AD_FORMAT_NAME (254): + Native ad format name. + + Corresponds to "Native ad format" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + NATIVE_STYLE_ID (253): + Native style ID. + + Corresponds to "Native style ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + NATIVE_STYLE_NAME (252): + Native style name. + + Corresponds to "Native style" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + NO_FILL_REASON_CATEGORY (586): + No fill reason category in the Ads traffic navigator report. + + Corresponds to "No fill reason category value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: + + Data format: ``ENUM`` + NO_FILL_REASON_CATEGORY_NAME (587): + No fill reason category name in the Ads traffic navigator + report. + + Corresponds to "No fill reason category" in the Ad Manager + UI. + + Compatible with the following report types: + + Data format: ``STRING`` + OPERATING_SYSTEM_CATEGORY (117): + Operating system category. + + Corresponds to "Operating system category value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``ENUM`` + OPERATING_SYSTEM_CATEGORY_NAME (118): + Operating system category name. + + Corresponds to "Operating system category" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + OPERATING_SYSTEM_VERSION_ID (238): + ID of the operating system version. + + Corresponds to "Operating system ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + OPERATING_SYSTEM_VERSION_NAME (237): + Details of the operating system, including version. + + Corresponds to "Operating system" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + OPTIMIZATION_TYPE (639): + Enum value of the optimization type. + + Corresponds to "Optimization type value" in the Ad Manager + UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + OPTIMIZATION_TYPE_NAME (640): + Localized name of the optimization type. + + Corresponds to "Optimization type" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + ORDER_AGENCY (150): + Order agency. + + Corresponds to "Order agency" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + ORDER_AGENCY_ID (151): + Order agency ID. + + Corresponds to "Order agency ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``IDENTIFIER`` + ORDER_BOOKED_CPC (152): + Order booked CPC. + + Corresponds to "Order booked CPC" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``INTEGER`` + ORDER_BOOKED_CPM (153): + Order booked CPM. + + Corresponds to "Order booked CPM" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``INTEGER`` + ORDER_DELIVERY_STATUS (231): + Order delivery status ENUM value. + + Corresponds to "Order delivery status value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + ORDER_DELIVERY_STATUS_NAME (239): + Order delivery status localized name. + + Corresponds to "Order delivery status" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + ORDER_END_DATE (154): + Order end date. + + Corresponds to "Order end date" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``DATE`` + ORDER_END_DATE_TIME (155): + Order end date and time. + + Corresponds to "Order end time" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``TIMESTAMP`` + ORDER_EXTERNAL_ID (156): + Order external ID. + + Corresponds to "Order external ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``IDENTIFIER`` + ORDER_ID (7): + Order ID. + + Corresponds to "Order ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + ORDER_LABELS (170): + Order labels. + + Corresponds to "Order labels" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING_LIST`` + ORDER_LABEL_IDS (171): + Order labels IDs. + + Corresponds to "Order label IDs" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``IDENTIFIER_LIST`` + ORDER_LIFETIME_CLICKS (158): + Order lifetime clicks. + + Corresponds to "Order lifetime clicks" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``INTEGER`` + ORDER_LIFETIME_IMPRESSIONS (159): + Order lifetime impressions. + + Corresponds to "Order lifetime impressions" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``INTEGER`` + ORDER_NAME (8): + Order name. + + Corresponds to "Order" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``STRING`` + ORDER_PO_NUMBER (160): + Order PO number. + + Corresponds to "Order PO number" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``STRING`` + ORDER_PROGRAMMATIC (157): + Whether the Order is programmatic. + + Corresponds to "Order is programmatic" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``BOOLEAN`` + ORDER_SALESPERSON (161): + Order sales person. + + Corresponds to "Order salesperson" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + ORDER_SALESPERSON_ID (629): + Order sales person ID. + + Corresponds to "Order salesperson ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``IDENTIFIER`` + ORDER_SECONDARY_SALESPEOPLE (164): + Order secondary sales people. + + Corresponds to "Order secondary salespeople" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING_LIST`` + ORDER_SECONDARY_SALESPEOPLE_ID (165): + Order secondary sales people ID. + + Corresponds to "Order secondary salespeople ID" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``IDENTIFIER_LIST`` + ORDER_SECONDARY_TRAFFICKERS (166): + Order secondary traffickers. + + Corresponds to "Order secondary traffickers" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING_LIST`` + ORDER_SECONDARY_TRAFFICKERS_ID (167): + Order secondary traffickers ID. + + Corresponds to "Order secondary trafficker IDs" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``IDENTIFIER_LIST`` + ORDER_START_DATE (168): + Order start date. + + Corresponds to "Order start date" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``DATE`` + ORDER_START_DATE_TIME (169): + Order start date and time. + + Corresponds to "Order start time" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``AD_SPEED`` + + Data format: ``TIMESTAMP`` + ORDER_TRAFFICKER (162): + Order trafficker. + + Corresponds to "Order trafficker" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + ORDER_TRAFFICKER_ID (163): + Order trafficker ID. + + Corresponds to "Order trafficker ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``IDENTIFIER`` + ORDER_UNLIMITED_END (203): + Whether the Order end time and end date is set to + effectively never end. + + Corresponds to "Order is unlimited end time" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``BOOLEAN`` + PAGE_PATH (511): + Page path is the part of a page URL that comes after the + domain but before the query strings from Google Analytics. + + Corresponds to "Page path" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + PAGE_TITLE_AND_SCREEN_CLASS (512): + Page title (web) and screen class (mobile) returned from + Google Analytics. + + Corresponds to "Page title and screen class" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + PAGE_TITLE_AND_SCREEN_NAME (513): + Page title (web) and screen name (mobile) returned from + Google Analytics. + + Corresponds to "Page title and screen name" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + PLACEMENT_ID (113): + Placement ID + + Corresponds to "Placement ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``IDENTIFIER`` + PLACEMENT_ID_ALL (144): + The full list of placement IDs associated with the ad unit. + + Corresponds to "Placement ID (all)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``IDENTIFIER_LIST`` + PLACEMENT_NAME (114): + Placement name + + Corresponds to "Placement" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + PLACEMENT_NAME_ALL (145): + The full list of placement names associated with the ad + unit. + + Corresponds to "Placement (all)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING_LIST`` + PLACEMENT_STATUS (362): + Placement status ENUM value + + Corresponds to "Placement status value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + PLACEMENT_STATUS_NAME (364): + Localized placement status name. + + Corresponds to "Placement status" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + PLACEMENT_STATUS_NAME_ALL (365): + The full list of localized placement status names associated + with the ad unit. + + Corresponds to "Placement status (all)" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING_LIST`` + POSTAL_CODE_ID (455): + The criteria ID of the postal code in which the ad served. + + Corresponds to "Postal code ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + POSTAL_CODE_NAME (456): + The name of the postal code in which the ad served. + + Corresponds to "Postal code" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + PPID_STATUS (406): + Indicates the valid PPID (Publisher provided identifier) + status on a given ad request. + + Corresponds to "PPID status value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + PPID_STATUS_NAME (407): + The localized name of that indicates the valid PPID + (Publisher provided identifier) status on a given ad + request. + + Corresponds to "PPID status" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + PREDICTED_VIEWABILITY_BUCKET (633): + Predicted viewability score bucket. + + Corresponds to "Predicted viewability bucket value" in the + Ad Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + PREDICTED_VIEWABILITY_BUCKET_NAME (634): + The localized name of the predicted viewability score + bucket. + + Corresponds to "Predicted viewability bucket" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + PRESENTED_SECURE_SIGNAL_ID (495): + The ID of the secure signals sent in the ad request. + + Corresponds to "Secure signal ID (presented)" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + PRESENTED_SECURE_SIGNAL_NAME (496): + The name of the secure signals sent in the ad request. + + Corresponds to "Secure signal name (presented)" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + PRIMARY_PERSONALIZATION_ID_TYPE (408): + The ID type selected for personalization. + + Corresponds to "Primary personalization ID type value" in + the Ad Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + PRIMARY_PERSONALIZATION_ID_TYPE_NAME (409): + The localized name of the ID type selected for + personalization. + + Corresponds to "Primary personalization ID type" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + PROGRAMMATIC_BUYER_ID (240): + Deprecated. Dimension has been renamed to ``DEAL_BUYER_ID``. + The server will normalize any requests using this value to + ``DEAL_BUYER_ID``. This value will be removed on or after + October 10, 2025. + PROGRAMMATIC_BUYER_NAME (241): + Deprecated. Dimension has been renamed to + ``DEAL_BUYER_NAME``. The server will normalize any requests + using this value to ``DEAL_BUYER_NAME``. This value will be + removed on or after October 10, 2025. + PROGRAMMATIC_CHANNEL (13): + Programmatic channel. The type of transaction that occurred + in Ad Exchange. + + Corresponds to "Programmatic channel value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + PROGRAMMATIC_CHANNEL_NAME (14): + Programmatic channel name. The type of transaction that + occurred in Ad Exchange. + + Corresponds to "Programmatic channel" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH`` + + Data format: ``STRING`` + PUBLISHER_PROVIDED_SIGNALS_ALL_LEVELS_EXTERNAL_CODE (410): + External code ID of a publisher provided signal (all + levels). + + Corresponds to "Publisher provided signals external code + (all levels)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + PUBLISHER_PROVIDED_SIGNALS_ALL_LEVELS_IDS (546): + The ancestor chain of IDs of a publisher provided signal + (all levels). + + Corresponds to "Publisher provided signals ID (all levels)" + in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER_LIST`` + PUBLISHER_PROVIDED_SIGNALS_ALL_LEVELS_NAME (412): + The ancestor chain of names of a publisher provided signal + (all levels). + + Corresponds to "Publisher provided signals (all levels)" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING_LIST`` + PUBLISHER_PROVIDED_SIGNALS_ALL_LEVELS_TIER (413): + Tier of a publisher provided signal (all levels). + + Corresponds to "Publisher provided signals tier (all + levels)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + PUBLISHER_PROVIDED_SIGNALS_ALL_LEVELS_TYPE (414): + Type of a publisher provided signal (all levels). + + Corresponds to "Publisher provided signals type (all + levels)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + PUBLISHER_PROVIDED_SIGNALS_DELIVERED_EXTERNAL_CODE (425): + External code ID of a publisher provided signal (delivered). + + Corresponds to "Publisher provided signals external code + (delivered)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + PUBLISHER_PROVIDED_SIGNALS_DELIVERED_IDS (545): + The ancestor chain of IDs of a publisher provided signal + (delivered). + + Corresponds to "Publisher provided signals ID (delivered)" + in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER_LIST`` + PUBLISHER_PROVIDED_SIGNALS_DELIVERED_NAME (427): + The ancestor chain of names of a publisher provided signal + (delivered). + + Corresponds to "Publisher provided signals (delivered)" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING_LIST`` + PUBLISHER_PROVIDED_SIGNALS_DELIVERED_TIER (428): + Tier of a publisher provided signal (delivered). + + Corresponds to "Publisher provided signals tier (delivered)" + in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + PUBLISHER_PROVIDED_SIGNALS_DELIVERED_TYPE (429): + Type of a publisher provided signal (delivered). + + Corresponds to "Publisher provided signals type (delivered)" + in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + PUBLISHER_PROVIDED_SIGNALS_TOP_LEVEL_EXTERNAL_CODE (415): + External code ID of a publisher provided signal (top level). + + Corresponds to "Publisher provided signals external code + (top level)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + PUBLISHER_PROVIDED_SIGNALS_TOP_LEVEL_ID (416): + ID of a publisher provided signal (top level). + + Corresponds to "Publisher provided signals ID (top level)" + in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + PUBLISHER_PROVIDED_SIGNALS_TOP_LEVEL_NAME (417): + Name of a publisher provided signal (top level). + + Corresponds to "Publisher provided signals (top level)" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING_LIST`` + PUBLISHER_PROVIDED_SIGNALS_TOP_LEVEL_TIER (418): + Tier of a publisher provided signal (top level). + + Corresponds to "Publisher provided signals tier (top level)" + in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + PUBLISHER_PROVIDED_SIGNALS_TOP_LEVEL_TYPE (419): + Type of a publisher provided signal (top level). + + Corresponds to "Publisher provided signals type (top level)" + in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + PUBLISHER_PROVIDED_SIGNAL_DATA_PROVIDER_ID (136): + Data provider ID associated with a publisher provided + signal. + + Corresponds to "Publisher provided signals (data provider + ID)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + PUBLISHER_PROVIDED_SIGNAL_DATA_PROVIDER_NAME (137): + Data provider name associated with a publisher provided + signal. + + Corresponds to "Publisher provided signals (data provider)" + in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + REGION_ID (457): + The criteria ID of the region (for example, US state) in + which the ad served. + + Corresponds to "Region ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``PRIVACY_AND_MESSAGING``, ``AD_SPEED`` + + Data format: ``IDENTIFIER`` + REGION_NAME (458): + The name of the region (for example, US state) in which the + ad served. + + Corresponds to "Region" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``PRIVACY_AND_MESSAGING``, ``AD_SPEED`` + + Data format: ``STRING`` + REJECTION_CLASS_CATEGORY (590): + The rejection class category in the Ads traffic navigator + report. + + Corresponds to "Rejection class category value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: + + Data format: ``ENUM`` + REJECTION_CLASS_CATEGORY_NAME (591): + The rejection class category name in the Ads traffic + navigator report. + + Corresponds to "Rejection class category" in the Ad Manager + UI. + + Compatible with the following report types: + + Data format: ``STRING`` + RENDERED_CREATIVE_SIZE (343): + The size of a rendered creative, It can differ with the + creative's size if a creative is shown in an ad slot of a + different size. + + Corresponds to "Rendered creative size" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + REQUESTED_AD_SIZES (352): + Inventory Requested Ad Sizes dimension + + Corresponds to "Requested ad sizes" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + REQUEST_TYPE (146): + Request type ENUM + + Corresponds to "Request type value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``ENUM`` + REQUEST_TYPE_NAME (147): + Request type locallized name + + Corresponds to "Request type" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``AD_SPEED`` + + Data format: ``STRING`` + SERVER_SIDE_UNWRAPPING_ELIGIBLE (597): + Indicates if a request was eligible for server-side + unwrapping. + + Corresponds to "Server-side unwrapping eligible" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``BOOLEAN`` + SERVING_RESTRICTION (631): + The serving restriction mode for privacy. + + Corresponds to "Serving restriction value" in the Ad Manager + UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + SERVING_RESTRICTION_NAME (632): + The localized name of the serving restriction mode for + privacy. + + Corresponds to "Serving restriction" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + SITE (387): + Information about domain or subdomains. + + Corresponds to "Site" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``PRIVACY_AND_MESSAGING`` + + Data format: ``STRING`` + TARGETING_ID (232): + The ID of the browser, device or other environment into + which a line item or creative was served. + + Corresponds to "Targeting ID" in the Ad Manager UI (when + showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + TARGETING_NAME (233): + Information about the browser, device and other environments + into which a line item or creative was served. + + Corresponds to "Targeting" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + TARGETING_TYPE (385): + The way in which advertisers targeted their ads. + + Corresponds to "Targeting type value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + TARGETING_TYPE_NAME (386): + The localized name of the way in which advertisers targeted + their ads. + + Corresponds to "Targeting type" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + THIRD_PARTY_ID_STATUS (402): + Whether a third-party cookie or device ID was present on a + given ad request. + + Corresponds to "Third-party ID status value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + THIRD_PARTY_ID_STATUS_NAME (403): + The localized name of whether a third-party cookie or device + ID was present on a given ad request. + + Corresponds to "Third-party ID status" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + TOPICS_STATUS (504): + Reports the status of Topics in the ad request. + + Corresponds to "Topics status value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + TOPICS_STATUS_NAME (505): + The localized name of the status of Topics in the ad + request. + + Corresponds to "Topics status" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + TOP_PRIVATE_DOMAIN (444): + Inventory top private domain dimension + + Corresponds to "Domain" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``PRIVACY_AND_MESSAGING`` + + Data format: ``STRING`` + TRAFFIC_SOURCE (388): + Inventory Traffic source dimension + + Corresponds to "Traffic source value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + TRAFFIC_SOURCE_NAME (389): + Inventory Traffic source dimension name + + Corresponds to "Traffic source" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + UNIFIED_PRICING_RULE_ID (393): + Unified pricing rule ID dimension + + Corresponds to "Unified pricing rule ID" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + UNIFIED_PRICING_RULE_NAME (394): + Unified pricing rule name dimension + + Corresponds to "Unified pricing rule" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + URL (506): + A URL defined under a publisher's inventory. + + Corresponds to "URL" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + URL_ID (507): + A URL defined under a publisher's inventory. + + Corresponds to "URL ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + USER_MESSAGES_ENTITLEMENT_SOURCE (635): + Enum value for the entitlement source. + + Corresponds to "Entitlement source value" in the Ad Manager + UI (when showing API fields). + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``ENUM`` + USER_MESSAGES_ENTITLEMENT_SOURCE_NAME (636): + The localized name of the entitlement source. + + Corresponds to "Entitlement source" in the Ad Manager UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``STRING`` + USER_MESSAGES_OPERATING_SYSTEM_CRITERIA_ID (637): + Targeting criteria ID for the operating system group. Used + for User Messages reports. + + Corresponds to "Operating system group ID" in the Ad Manager + UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``INTEGER`` + USER_MESSAGES_OPERATING_SYSTEM_CRITERIA_NAME (638): + The name of the operating system group. Used for User + Messages reports. + + Corresponds to "Operating system group" in the Ad Manager + UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``STRING`` + VAST_VERSION (554): + The VAST version of the creative that is returned for an ad + request. + + Corresponds to "Vast version value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + VAST_VERSION_NAME (555): + The localized name of the VAST version of the creative that + is returned for an ad request. + + Corresponds to "Vast version" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + VIDEO_AD_BREAK_TYPE (556): + The break type of a video ad request. + + Corresponds to "Video ad break type value" in the Ad Manager + UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + VIDEO_AD_BREAK_TYPE_NAME (557): + The localized name of the break type of a video ad request. + + Corresponds to "Video ad break type" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + VIDEO_AD_DURATION (450): + Video ad duration + + Corresponds to "Video ad duration" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + VIDEO_AD_FORMATS_RULE (561): + The name of the video ad formats rule used to control the ad + formats eligible for your inventory. + + Corresponds to "Video ad formats rule" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + VIDEO_AD_FORMATS_RULE_ID (560): + The ID of the video ad formats rule used to control the ad + formats eligible for your inventory. + + Corresponds to "Video ad formats rule ID" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + VIDEO_AD_REQUEST_DURATION (558): + The duration of a video ad request. + + Corresponds to "Video ad request duration value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + VIDEO_AD_REQUEST_DURATION_MIDPOINT_NAME (751): + The localized name of the midpoint of the duration of a + video ad request. + + Corresponds to "Video ad request duration midpoint" in the + Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + VIDEO_AD_REQUEST_DURATION_NAME (559): + The localized name of the duration of a video ad request. + + Corresponds to "Video ad request duration" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + VIDEO_AD_REQUEST_SOURCE (438): + The video ad request source enum. + + Corresponds to "Ad request source value" in the Ad Manager + UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + VIDEO_AD_REQUEST_SOURCE_NAME (439): + The localized name of the video ad request source. + + Corresponds to "Ad request source" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + VIDEO_AD_TYPE (432): + Video ad type + + Corresponds to "Video ad type value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + VIDEO_AD_TYPE_NAME (433): + Video ad type localized name + + Corresponds to "Video ad type" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + VIDEO_CONTINUOUS_PLAY_TYPE (721): + The continuous play type of the video ad impression. + + Corresponds to "Video continuous play type value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + VIDEO_CONTINUOUS_PLAY_TYPE_NAME (722): + Video continuous play type localized name. + + Corresponds to "Video continuous play type" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + VIDEO_FALLBACK_POSITION (530): + Fallback position of the video ad. + + Corresponds to "Fallback position" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + VIDEO_MEASUREMENT_SOURCE (601): + The performance of the video ad inventory broken out by + source. + + Corresponds to "Video measurement source value" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + VIDEO_MEASUREMENT_SOURCE_NAME (602): + Video measurement source localized name. + + Corresponds to "Video measurement source" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + VIDEO_PLCMT (172): + The video placement enum as defined by ADCOM 1.0-202303. + + Corresponds to "Video placement value (new)" in the Ad + Manager UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + VIDEO_PLCMT_NAME (173): + The localized name of the video placement as defined by + ADCOM 1.0-202303. + + Corresponds to "Video placement (new)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + VIDEO_POSITION_IN_POD (538): + The position in the video pod. For example 0, 1, 2, etc. + + Corresponds to "Position in pod" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + VIDEO_POSITION_OF_POD (539): + The position of the pod in the video stream. For example + pre-roll, mid-roll, post-roll. + + Corresponds to "Position of pod" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + VIDEO_SDK_VERSION (440): + The video SDK version enum. + + Corresponds to "Video SDK version value" in the Ad Manager + UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + VIDEO_SDK_VERSION_NAME (441): + The localized name of the video SDK version. + + Corresponds to "Video SDK version" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + VIDEO_STITCHER_TYPE (752): + Video stitcher type. + + Corresponds to "Video stitcher type value" in the Ad Manager + UI (when showing API fields). + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``ENUM`` + VIDEO_STITCHER_TYPE_NAME (753): + Localized name of the video stitcher type. + + Corresponds to "Video stitcher type" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + WEEK (5): + Breaks down reporting data by week of the year. + + Corresponds to "Week" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL``, + ``REACH``, ``PRIVACY_AND_MESSAGING`` + + Data format: ``INTEGER`` + YIELD_GROUP_BUYER_NAME (184): + Name of the company within a yield group + + Corresponds to "Yield partner" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + YIELD_GROUP_BUYER_TAG_NAME (627): + Tag of the company within a yield group. + + Corresponds to "Yield group buyer tag" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + YIELD_GROUP_ID (182): + ID of the group of ad networks or exchanges used for + Mediation and Open Bidding + + Corresponds to "Yield group ID" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``IDENTIFIER`` + YIELD_GROUP_NAME (183): + Name of the group of ad networks or exchanges used for + Mediation and Open Bidding + + Corresponds to "Yield group" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``STRING`` + YOUTUBE_AD_DURATION_BUCKET (430): + YouTube instream ad duration bucket. + + Corresponds to "Ad duration value" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: + + Data format: ``ENUM`` + YOUTUBE_AD_DURATION_BUCKET_NAME (431): + YouTube instream ad duration bucket name. + + Corresponds to "Ad duration" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``STRING`` + YOUTUBE_AD_TYPE (399): + YouTube instream Ad Type. + + Corresponds to "YouTube ad type ID" in the Ad Manager UI + (when showing API fields). + + Compatible with the following report types: + + Data format: ``ENUM`` + YOUTUBE_AD_TYPE_NAME (400): + YouTube instream Ad Type locallized name. + + Corresponds to "YouTube ad type" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``STRING`` + LINE_ITEM_CUSTOM_FIELD_0_OPTION_ID (10000): + Custom field option ID for Line Item with custom field ID + equal to the ID in index 0 of + ``ReportDefinition.line_item_custom_field_ids``. + LINE_ITEM_CUSTOM_FIELD_1_OPTION_ID (10001): + Custom field option ID for Line Item with custom field ID + equal to the ID in index 1 of + ``ReportDefinition.line_item_custom_field_ids``. + LINE_ITEM_CUSTOM_FIELD_2_OPTION_ID (10002): + Custom field option ID for Line Item with custom field ID + equal to the ID in index 2 of + ``ReportDefinition.line_item_custom_field_ids``. + LINE_ITEM_CUSTOM_FIELD_3_OPTION_ID (10003): + Custom field option ID for Line Item with custom field ID + equal to the ID in index 3 of + ``ReportDefinition.line_item_custom_field_ids``. + LINE_ITEM_CUSTOM_FIELD_4_OPTION_ID (10004): + Custom field option ID for Line Item with custom field ID + equal to the ID in index 4 of + ``ReportDefinition.line_item_custom_field_ids``. + LINE_ITEM_CUSTOM_FIELD_5_OPTION_ID (10005): + Custom field option ID for Line Item with custom field ID + equal to the ID in index 5 of + ``ReportDefinition.line_item_custom_field_ids``. + LINE_ITEM_CUSTOM_FIELD_6_OPTION_ID (10006): + Custom field option ID for Line Item with custom field ID + equal to the ID in index 6 of + ``ReportDefinition.line_item_custom_field_ids``. + LINE_ITEM_CUSTOM_FIELD_7_OPTION_ID (10007): + Custom field option ID for Line Item with custom field ID + equal to the ID in index 7 of + ``ReportDefinition.line_item_custom_field_ids``. + LINE_ITEM_CUSTOM_FIELD_8_OPTION_ID (10008): + Custom field option ID for Line Item with custom field ID + equal to the ID in index 8 of + ``ReportDefinition.line_item_custom_field_ids``. + LINE_ITEM_CUSTOM_FIELD_9_OPTION_ID (10009): + Custom field option ID for Line Item with custom field ID + equal to the ID in index 9 of + ``ReportDefinition.line_item_custom_field_ids``. + LINE_ITEM_CUSTOM_FIELD_10_OPTION_ID (10010): + Custom field option ID for Line Item with custom field ID + equal to the ID in index 10 of + ``ReportDefinition.line_item_custom_field_ids``. + LINE_ITEM_CUSTOM_FIELD_11_OPTION_ID (10011): + Custom field option ID for Line Item with custom field ID + equal to the ID in index 11 of + ``ReportDefinition.line_item_custom_field_ids``. + LINE_ITEM_CUSTOM_FIELD_12_OPTION_ID (10012): + Custom field option ID for Line Item with custom field ID + equal to the ID in index 12 of + ``ReportDefinition.line_item_custom_field_ids``. + LINE_ITEM_CUSTOM_FIELD_13_OPTION_ID (10013): + Custom field option ID for Line Item with custom field ID + equal to the ID in index 13 of + ``ReportDefinition.line_item_custom_field_ids``. + LINE_ITEM_CUSTOM_FIELD_14_OPTION_ID (10014): + Custom field option ID for Line Item with custom field ID + equal to the ID in index 14 of + ``ReportDefinition.line_item_custom_field_ids``. + LINE_ITEM_CUSTOM_FIELD_0_VALUE (11000): + Custom field value for Line Item with custom field ID equal + to the ID in index 0 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 0 is of type ``STRING`` or ``DROPDOWN``. + LINE_ITEM_CUSTOM_FIELD_1_VALUE (11001): + Custom field value for Line Item with custom field ID equal + to the ID in index 1 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 1 is of type ``STRING`` or ``DROPDOWN``. + LINE_ITEM_CUSTOM_FIELD_2_VALUE (11002): + Custom field value for Line Item with custom field ID equal + to the ID in index 2 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 2 is of type ``STRING`` or ``DROPDOWN``. + LINE_ITEM_CUSTOM_FIELD_3_VALUE (11003): + Custom field value for Line Item with custom field ID equal + to the ID in index 3 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 3 is of type ``STRING`` or ``DROPDOWN``. + LINE_ITEM_CUSTOM_FIELD_4_VALUE (11004): + Custom field value for Line Item with custom field ID equal + to the ID in index 4 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 4 is of type ``STRING`` or ``DROPDOWN``. + LINE_ITEM_CUSTOM_FIELD_5_VALUE (11005): + Custom field value for Line Item with custom field ID equal + to the ID in index 5 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 5 is of type ``STRING`` or ``DROPDOWN``. + LINE_ITEM_CUSTOM_FIELD_6_VALUE (11006): + Custom field value for Line Item with custom field ID equal + to the ID in index 6 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 6 is of type ``STRING`` or ``DROPDOWN``. + LINE_ITEM_CUSTOM_FIELD_7_VALUE (11007): + Custom field value for Line Item with custom field ID equal + to the ID in index 7 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 7 is of type ``STRING`` or ``DROPDOWN``. + LINE_ITEM_CUSTOM_FIELD_8_VALUE (11008): + Custom field value for Line Item with custom field ID equal + to the ID in index 8 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 8 is of type ``STRING`` or ``DROPDOWN``. + LINE_ITEM_CUSTOM_FIELD_9_VALUE (11009): + Custom field value for Line Item with custom field ID equal + to the ID in index 9 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 9 is of type ``STRING`` or ``DROPDOWN``. + LINE_ITEM_CUSTOM_FIELD_10_VALUE (11010): + Custom field value for Line Item with custom field ID equal + to the ID in index 10 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 10 is of type ``STRING`` or ``DROPDOWN``. + LINE_ITEM_CUSTOM_FIELD_11_VALUE (11011): + Custom field value for Line Item with custom field ID equal + to the ID in index 11 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 11 is of type ``STRING`` or ``DROPDOWN``. + LINE_ITEM_CUSTOM_FIELD_12_VALUE (11012): + Custom field value for Line Item with custom field ID equal + to the ID in index 12 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 12 is of type ``STRING`` or ``DROPDOWN``. + LINE_ITEM_CUSTOM_FIELD_13_VALUE (11013): + Custom field value for Line Item with custom field ID equal + to the ID in index 13 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 13 is of type ``STRING`` or ``DROPDOWN``. + LINE_ITEM_CUSTOM_FIELD_14_VALUE (11014): + Custom field value for Line Item with custom field ID equal + to the ID in index 14 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 14 is of type ``STRING`` or ``DROPDOWN``. + ORDER_CUSTOM_FIELD_0_OPTION_ID (12000): + Custom field option ID for Order with custom field ID equal + to the ID in index 0 of + ``ReportDefinition.order_custom_field_ids``. + ORDER_CUSTOM_FIELD_1_OPTION_ID (12001): + Custom field option ID for Order with custom field ID equal + to the ID in index 1 of + ``ReportDefinition.order_custom_field_ids``. + ORDER_CUSTOM_FIELD_2_OPTION_ID (12002): + Custom field option ID for Order with custom field ID equal + to the ID in index 2 of + ``ReportDefinition.order_custom_field_ids``. + ORDER_CUSTOM_FIELD_3_OPTION_ID (12003): + Custom field option ID for Order with custom field ID equal + to the ID in index 3 of + ``ReportDefinition.order_custom_field_ids``. + ORDER_CUSTOM_FIELD_4_OPTION_ID (12004): + Custom field option ID for Order with custom field ID equal + to the ID in index 4 of + ``ReportDefinition.order_custom_field_ids``. + ORDER_CUSTOM_FIELD_5_OPTION_ID (12005): + Custom field option ID for Order with custom field ID equal + to the ID in index 5 of + ``ReportDefinition.order_custom_field_ids``. + ORDER_CUSTOM_FIELD_6_OPTION_ID (12006): + Custom field option ID for Order with custom field ID equal + to the ID in index 6 of + ``ReportDefinition.order_custom_field_ids``. + ORDER_CUSTOM_FIELD_7_OPTION_ID (12007): + Custom field option ID for Order with custom field ID equal + to the ID in index 7 of + ``ReportDefinition.order_custom_field_ids``. + ORDER_CUSTOM_FIELD_8_OPTION_ID (12008): + Custom field option ID for Order with custom field ID equal + to the ID in index 8 of + ``ReportDefinition.order_custom_field_ids``. + ORDER_CUSTOM_FIELD_9_OPTION_ID (12009): + Custom field option ID for Order with custom field ID equal + to the ID in index 9 of + ``ReportDefinition.order_custom_field_ids``. + ORDER_CUSTOM_FIELD_10_OPTION_ID (12010): + Custom field option ID for Order with custom field ID equal + to the ID in index 10 of + ``ReportDefinition.order_custom_field_ids``. + ORDER_CUSTOM_FIELD_11_OPTION_ID (12011): + Custom field option ID for Order with custom field ID equal + to the ID in index 11 of + ``ReportDefinition.order_custom_field_ids``. + ORDER_CUSTOM_FIELD_12_OPTION_ID (12012): + Custom field option ID for Order with custom field ID equal + to the ID in index 12 of + ``ReportDefinition.order_custom_field_ids``. + ORDER_CUSTOM_FIELD_13_OPTION_ID (12013): + Custom field option ID for Order with custom field ID equal + to the ID in index 13 of + ``ReportDefinition.order_custom_field_ids``. + ORDER_CUSTOM_FIELD_14_OPTION_ID (12014): + Custom field option ID for Order with custom field ID equal + to the ID in index 14 of + ``ReportDefinition.order_custom_field_ids``. + ORDER_CUSTOM_FIELD_0_VALUE (13000): + Custom field value for Order with custom field ID equal to + the ID in index 0 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 0 is of type STRING. + ORDER_CUSTOM_FIELD_1_VALUE (13001): + Custom field value for Order with custom field ID equal to + the ID in index 1 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 1 is of type STRING. + ORDER_CUSTOM_FIELD_2_VALUE (13002): + Custom field value for Order with custom field ID equal to + the ID in index 2 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 2 is of type STRING. + ORDER_CUSTOM_FIELD_3_VALUE (13003): + Custom field value for Order with custom field ID equal to + the ID in index 3 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 3 is of type STRING. + ORDER_CUSTOM_FIELD_4_VALUE (13004): + Custom field value for Order with custom field ID equal to + the ID in index 4 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 4 is of type STRING. + ORDER_CUSTOM_FIELD_5_VALUE (13005): + Custom field value for Order with custom field ID equal to + the ID in index 5 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 5 is of type STRING. + ORDER_CUSTOM_FIELD_6_VALUE (13006): + Custom field value for Order with custom field ID equal to + the ID in index 6 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 6 is of type STRING. + ORDER_CUSTOM_FIELD_7_VALUE (13007): + Custom field value for Order with custom field ID equal to + the ID in index 7 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 7 is of type STRING. + ORDER_CUSTOM_FIELD_8_VALUE (13008): + Custom field value for Order with custom field ID equal to + the ID in index 8 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 8 is of type STRING. + ORDER_CUSTOM_FIELD_9_VALUE (13009): + Custom field value for Order with custom field ID equal to + the ID in index 9 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 9 is of type STRING. + ORDER_CUSTOM_FIELD_10_VALUE (13010): + Custom field value for Order with custom field ID equal to + the ID in index 10 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 10 is of type STRING. + ORDER_CUSTOM_FIELD_11_VALUE (13011): + Custom field value for Order with custom field ID equal to + the ID in index 11 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 11 is of type STRING. + ORDER_CUSTOM_FIELD_12_VALUE (13012): + Custom field value for Order with custom field ID equal to + the ID in index 12 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 12 is of type STRING. + ORDER_CUSTOM_FIELD_13_VALUE (13013): + Custom field value for Order with custom field ID equal to + the ID in index 13 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 13 is of type STRING. + ORDER_CUSTOM_FIELD_14_VALUE (13014): + Custom field value for Order with custom field ID equal to + the ID in index 14 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 14 is of type STRING. + CREATIVE_CUSTOM_FIELD_0_OPTION_ID (14000): + Custom field option ID for Creative with custom field ID + equal to the ID in index 0 of + ``ReportDefinition.creative_custom_field_ids``. + CREATIVE_CUSTOM_FIELD_1_OPTION_ID (14001): + Custom field option ID for Creative with custom field ID + equal to the ID in index 1 of + ``ReportDefinition.creative_custom_field_ids``. + CREATIVE_CUSTOM_FIELD_2_OPTION_ID (14002): + Custom field option ID for Creative with custom field ID + equal to the ID in index 2 of + ``ReportDefinition.creative_custom_field_ids``. + CREATIVE_CUSTOM_FIELD_3_OPTION_ID (14003): + Custom field option ID for Creative with custom field ID + equal to the ID in index 3 of + ``ReportDefinition.creative_custom_field_ids``. + CREATIVE_CUSTOM_FIELD_4_OPTION_ID (14004): + Custom field option ID for Creative with custom field ID + equal to the ID in index 4 of + ``ReportDefinition.creative_custom_field_ids``. + CREATIVE_CUSTOM_FIELD_5_OPTION_ID (14005): + Custom field option ID for Creative with custom field ID + equal to the ID in index 5 of + ``ReportDefinition.creative_custom_field_ids``. + CREATIVE_CUSTOM_FIELD_6_OPTION_ID (14006): + Custom field option ID for Creative with custom field ID + equal to the ID in index 6 of + ``ReportDefinition.creative_custom_field_ids``. + CREATIVE_CUSTOM_FIELD_7_OPTION_ID (14007): + Custom field option ID for Creative with custom field ID + equal to the ID in index 7 of + ``ReportDefinition.creative_custom_field_ids``. + CREATIVE_CUSTOM_FIELD_8_OPTION_ID (14008): + Custom field option ID for Creative with custom field ID + equal to the ID in index 8 of + ``ReportDefinition.creative_custom_field_ids``. + CREATIVE_CUSTOM_FIELD_9_OPTION_ID (14009): + Custom field option ID for Creative with custom field ID + equal to the ID in index 9 of + ``ReportDefinition.creative_custom_field_ids``. + CREATIVE_CUSTOM_FIELD_10_OPTION_ID (14010): + Custom field option ID for Creative with custom field ID + equal to the ID in index 10 of + ``ReportDefinition.creative_custom_field_ids``. + CREATIVE_CUSTOM_FIELD_11_OPTION_ID (14011): + Custom field option ID for Creative with custom field ID + equal to the ID in index 11 of + ``ReportDefinition.creative_custom_field_ids``. + CREATIVE_CUSTOM_FIELD_12_OPTION_ID (14012): + Custom field option ID for Creative with custom field ID + equal to the ID in index 12 of + ``ReportDefinition.creative_custom_field_ids``. + CREATIVE_CUSTOM_FIELD_13_OPTION_ID (14013): + Custom field option ID for Creative with custom field ID + equal to the ID in index 13 of + ``ReportDefinition.creative_custom_field_ids``. + CREATIVE_CUSTOM_FIELD_14_OPTION_ID (14014): + Custom field option ID for Creative with custom field ID + equal to the ID in index 14 of + ``ReportDefinition.creative_custom_field_ids``. + CREATIVE_CUSTOM_FIELD_0_VALUE (15000): + Custom field value for Creative with custom field ID equal + to the ID in index 0 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 0 is of type STRING. + CREATIVE_CUSTOM_FIELD_1_VALUE (15001): + Custom field value for Creative with custom field ID equal + to the ID in index 1 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 1 is of type STRING. + CREATIVE_CUSTOM_FIELD_2_VALUE (15002): + Custom field value for Creative with custom field ID equal + to the ID in index 2 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 2 is of type STRING. + CREATIVE_CUSTOM_FIELD_3_VALUE (15003): + Custom field value for Creative with custom field ID equal + to the ID in index 3 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 3 is of type STRING. + CREATIVE_CUSTOM_FIELD_4_VALUE (15004): + Custom field value for Creative with custom field ID equal + to the ID in index 4 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 4 is of type STRING. + CREATIVE_CUSTOM_FIELD_5_VALUE (15005): + Custom field value for Creative with custom field ID equal + to the ID in index 5 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 5 is of type STRING. + CREATIVE_CUSTOM_FIELD_6_VALUE (15006): + Custom field value for Creative with custom field ID equal + to the ID in index 6 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 6 is of type STRING. + CREATIVE_CUSTOM_FIELD_7_VALUE (15007): + Custom field value for Creative with custom field ID equal + to the ID in index 7 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 7 is of type STRING. + CREATIVE_CUSTOM_FIELD_8_VALUE (15008): + Custom field value for Creative with custom field ID equal + to the ID in index 8 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 8 is of type STRING. + CREATIVE_CUSTOM_FIELD_9_VALUE (15009): + Custom field value for Creative with custom field ID equal + to the ID in index 9 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 9 is of type STRING. + CREATIVE_CUSTOM_FIELD_10_VALUE (15010): + Custom field value for Creative with custom field ID equal + to the ID in index 10 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 10 is of type STRING. + CREATIVE_CUSTOM_FIELD_11_VALUE (15011): + Custom field value for Creative with custom field ID equal + to the ID in index 11 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 11 is of type STRING. + CREATIVE_CUSTOM_FIELD_12_VALUE (15012): + Custom field value for Creative with custom field ID equal + to the ID in index 12 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 12 is of type STRING. + CREATIVE_CUSTOM_FIELD_13_VALUE (15013): + Custom field value for Creative with custom field ID equal + to the ID in index 13 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 13 is of type STRING. + CREATIVE_CUSTOM_FIELD_14_VALUE (15014): + Custom field value for Creative with custom field ID equal + to the ID in index 14 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 14 is of type STRING. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_0_OPTION_ID (16000): + Custom field option ID for Backfill line item with custom + field ID equal to the ID in index 0 of + ``ReportDefinition.line_item_custom_field_ids``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_1_OPTION_ID (16001): + Custom field option ID for Backfill line item with custom + field ID equal to the ID in index 1 of + ``ReportDefinition.line_item_custom_field_ids``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_2_OPTION_ID (16002): + Custom field option ID for Backfill line item with custom + field ID equal to the ID in index 2 of + ``ReportDefinition.line_item_custom_field_ids``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_3_OPTION_ID (16003): + Custom field option ID for Backfill line item with custom + field ID equal to the ID in index 3 of + ``ReportDefinition.line_item_custom_field_ids``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_4_OPTION_ID (16004): + Custom field option ID for Backfill line item with custom + field ID equal to the ID in index 4 of + ``ReportDefinition.line_item_custom_field_ids``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_5_OPTION_ID (16005): + Custom field option ID for Backfill line item with custom + field ID equal to the ID in index 5 of + ``ReportDefinition.line_item_custom_field_ids``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_6_OPTION_ID (16006): + Custom field option ID for Backfill line item with custom + field ID equal to the ID in index 6 of + ``ReportDefinition.line_item_custom_field_ids``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_7_OPTION_ID (16007): + Custom field option ID for Backfill line item with custom + field ID equal to the ID in index 7 of + ``ReportDefinition.line_item_custom_field_ids``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_8_OPTION_ID (16008): + Custom field option ID for Backfill line item with custom + field ID equal to the ID in index 8 of + ``ReportDefinition.line_item_custom_field_ids``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_9_OPTION_ID (16009): + Custom field option ID for Backfill line item with custom + field ID equal to the ID in index 9 of + ``ReportDefinition.line_item_custom_field_ids``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_10_OPTION_ID (16010): + Custom field option ID for Backfill line item with custom + field ID equal to the ID in index 10 of + ``ReportDefinition.line_item_custom_field_ids``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_11_OPTION_ID (16011): + Custom field option ID for Backfill line item with custom + field ID equal to the ID in index 11 of + ``ReportDefinition.line_item_custom_field_ids``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_12_OPTION_ID (16012): + Custom field option ID for Backfill line item with custom + field ID equal to the ID in index 12 of + ``ReportDefinition.line_item_custom_field_ids``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_13_OPTION_ID (16013): + Custom field option ID for Backfill line item with custom + field ID equal to the ID in index 13 of + ``ReportDefinition.line_item_custom_field_ids``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_14_OPTION_ID (16014): + Custom field option ID for Backfill line item with custom + field ID equal to the ID in index 14 of + ``ReportDefinition.line_item_custom_field_ids``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_0_VALUE (17000): + Custom field value for Backfill line item with custom field + ID equal to the ID in index 0 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 0 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_1_VALUE (17001): + Custom field value for Backfill line item with custom field + ID equal to the ID in index 1 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 1 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_2_VALUE (17002): + Custom field value for Backfill line item with custom field + ID equal to the ID in index 2 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 2 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_3_VALUE (17003): + Custom field value for Backfill line item with custom field + ID equal to the ID in index 3 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 3 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_4_VALUE (17004): + Custom field value for Backfill line item with custom field + ID equal to the ID in index 4 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 4 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_5_VALUE (17005): + Custom field value for Backfill line item with custom field + ID equal to the ID in index 5 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 5 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_6_VALUE (17006): + Custom field value for Backfill line item with custom field + ID equal to the ID in index 6 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 6 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_7_VALUE (17007): + Custom field value for Backfill line item with custom field + ID equal to the ID in index 7 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 7 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_8_VALUE (17008): + Custom field value for Backfill line item with custom field + ID equal to the ID in index 8 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 8 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_9_VALUE (17009): + Custom field value for Backfill line item with custom field + ID equal to the ID in index 9 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 9 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_10_VALUE (17010): + Custom field value for Backfill line item with custom field + ID equal to the ID in index 10 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 10 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_11_VALUE (17011): + Custom field value for Backfill line item with custom field + ID equal to the ID in index 11 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 11 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_12_VALUE (17012): + Custom field value for Backfill line item with custom field + ID equal to the ID in index 12 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 12 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_13_VALUE (17013): + Custom field value for Backfill line item with custom field + ID equal to the ID in index 13 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 13 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_LINE_ITEM_CUSTOM_FIELD_14_VALUE (17014): + Custom field value for Backfill line item with custom field + ID equal to the ID in index 14 of + ``ReportDefinition.line_item_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 14 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_ORDER_CUSTOM_FIELD_0_OPTION_ID (18000): + Custom field option ID for Backfill order with custom field + ID equal to the ID in index 0 of + ``ReportDefinition.order_custom_field_ids``. + BACKFILL_ORDER_CUSTOM_FIELD_1_OPTION_ID (18001): + Custom field option ID for Backfill order with custom field + ID equal to the ID in index 1 of + ``ReportDefinition.order_custom_field_ids``. + BACKFILL_ORDER_CUSTOM_FIELD_2_OPTION_ID (18002): + Custom field option ID for Backfill order with custom field + ID equal to the ID in index 2 of + ``ReportDefinition.order_custom_field_ids``. + BACKFILL_ORDER_CUSTOM_FIELD_3_OPTION_ID (18003): + Custom field option ID for Backfill order with custom field + ID equal to the ID in index 3 of + ``ReportDefinition.order_custom_field_ids``. + BACKFILL_ORDER_CUSTOM_FIELD_4_OPTION_ID (18004): + Custom field option ID for Backfill order with custom field + ID equal to the ID in index 4 of + ``ReportDefinition.order_custom_field_ids``. + BACKFILL_ORDER_CUSTOM_FIELD_5_OPTION_ID (18005): + Custom field option ID for Backfill order with custom field + ID equal to the ID in index 5 of + ``ReportDefinition.order_custom_field_ids``. + BACKFILL_ORDER_CUSTOM_FIELD_6_OPTION_ID (18006): + Custom field option ID for Backfill order with custom field + ID equal to the ID in index 6 of + ``ReportDefinition.order_custom_field_ids``. + BACKFILL_ORDER_CUSTOM_FIELD_7_OPTION_ID (18007): + Custom field option ID for Backfill order with custom field + ID equal to the ID in index 7 of + ``ReportDefinition.order_custom_field_ids``. + BACKFILL_ORDER_CUSTOM_FIELD_8_OPTION_ID (18008): + Custom field option ID for Backfill order with custom field + ID equal to the ID in index 8 of + ``ReportDefinition.order_custom_field_ids``. + BACKFILL_ORDER_CUSTOM_FIELD_9_OPTION_ID (18009): + Custom field option ID for Backfill order with custom field + ID equal to the ID in index 9 of + ``ReportDefinition.order_custom_field_ids``. + BACKFILL_ORDER_CUSTOM_FIELD_10_OPTION_ID (18010): + Custom field option ID for Backfill order with custom field + ID equal to the ID in index 10 of + ``ReportDefinition.order_custom_field_ids``. + BACKFILL_ORDER_CUSTOM_FIELD_11_OPTION_ID (18011): + Custom field option ID for Backfill order with custom field + ID equal to the ID in index 11 of + ``ReportDefinition.order_custom_field_ids``. + BACKFILL_ORDER_CUSTOM_FIELD_12_OPTION_ID (18012): + Custom field option ID for Backfill order with custom field + ID equal to the ID in index 12 of + ``ReportDefinition.order_custom_field_ids``. + BACKFILL_ORDER_CUSTOM_FIELD_13_OPTION_ID (18013): + Custom field option ID for Backfill order with custom field + ID equal to the ID in index 13 of + ``ReportDefinition.order_custom_field_ids``. + BACKFILL_ORDER_CUSTOM_FIELD_14_OPTION_ID (18014): + Custom field option ID for Backfill order with custom field + ID equal to the ID in index 14 of + ``ReportDefinition.order_custom_field_ids``. + BACKFILL_ORDER_CUSTOM_FIELD_0_VALUE (19000): + Custom field value for Backfill order with custom field ID + equal to the ID in index 0 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 0 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_ORDER_CUSTOM_FIELD_1_VALUE (19001): + Custom field value for Backfill order with custom field ID + equal to the ID in index 1 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 1 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_ORDER_CUSTOM_FIELD_2_VALUE (19002): + Custom field value for Backfill order with custom field ID + equal to the ID in index 2 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 2 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_ORDER_CUSTOM_FIELD_3_VALUE (19003): + Custom field value for Backfill order with custom field ID + equal to the ID in index 3 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 3 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_ORDER_CUSTOM_FIELD_4_VALUE (19004): + Custom field value for Backfill order with custom field ID + equal to the ID in index 4 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 4 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_ORDER_CUSTOM_FIELD_5_VALUE (19005): + Custom field value for Backfill order with custom field ID + equal to the ID in index 5 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 5 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_ORDER_CUSTOM_FIELD_6_VALUE (19006): + Custom field value for Backfill order with custom field ID + equal to the ID in index 6 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 6 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_ORDER_CUSTOM_FIELD_7_VALUE (19007): + Custom field value for Backfill order with custom field ID + equal to the ID in index 7 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 7 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_ORDER_CUSTOM_FIELD_8_VALUE (19008): + Custom field value for Backfill order with custom field ID + equal to the ID in index 8 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 8 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_ORDER_CUSTOM_FIELD_9_VALUE (19009): + Custom field value for Backfill order with custom field ID + equal to the ID in index 9 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 9 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_ORDER_CUSTOM_FIELD_10_VALUE (19010): + Custom field value for Backfill order with custom field ID + equal to the ID in index 10 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 10 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_ORDER_CUSTOM_FIELD_11_VALUE (19011): + Custom field value for Backfill order with custom field ID + equal to the ID in index 11 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 11 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_ORDER_CUSTOM_FIELD_12_VALUE (19012): + Custom field value for Backfill order with custom field ID + equal to the ID in index 12 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 12 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_ORDER_CUSTOM_FIELD_13_VALUE (19013): + Custom field value for Backfill order with custom field ID + equal to the ID in index 13 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 13 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_ORDER_CUSTOM_FIELD_14_VALUE (19014): + Custom field value for Backfill order with custom field ID + equal to the ID in index 14 of + ``ReportDefinition.order_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 14 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_CREATIVE_CUSTOM_FIELD_0_OPTION_ID (20000): + Custom field option ID for Backfill creative with custom + field ID equal to the ID in index 0 of + ``ReportDefinition.creative_custom_field_ids``. + BACKFILL_CREATIVE_CUSTOM_FIELD_1_OPTION_ID (20001): + Custom field option ID for Backfill creative with custom + field ID equal to the ID in index 1 of + ``ReportDefinition.creative_custom_field_ids``. + BACKFILL_CREATIVE_CUSTOM_FIELD_2_OPTION_ID (20002): + Custom field option ID for Backfill creative with custom + field ID equal to the ID in index 2 of + ``ReportDefinition.creative_custom_field_ids``. + BACKFILL_CREATIVE_CUSTOM_FIELD_3_OPTION_ID (20003): + Custom field option ID for Backfill creative with custom + field ID equal to the ID in index 3 of + ``ReportDefinition.creative_custom_field_ids``. + BACKFILL_CREATIVE_CUSTOM_FIELD_4_OPTION_ID (20004): + Custom field option ID for Backfill creative with custom + field ID equal to the ID in index 4 of + ``ReportDefinition.creative_custom_field_ids``. + BACKFILL_CREATIVE_CUSTOM_FIELD_5_OPTION_ID (20005): + Custom field option ID for Backfill creative with custom + field ID equal to the ID in index 5 of + ``ReportDefinition.creative_custom_field_ids``. + BACKFILL_CREATIVE_CUSTOM_FIELD_6_OPTION_ID (20006): + Custom field option ID for Backfill creative with custom + field ID equal to the ID in index 6 of + ``ReportDefinition.creative_custom_field_ids``. + BACKFILL_CREATIVE_CUSTOM_FIELD_7_OPTION_ID (20007): + Custom field option ID for Backfill creative with custom + field ID equal to the ID in index 7 of + ``ReportDefinition.creative_custom_field_ids``. + BACKFILL_CREATIVE_CUSTOM_FIELD_8_OPTION_ID (20008): + Custom field option ID for Backfill creative with custom + field ID equal to the ID in index 8 of + ``ReportDefinition.creative_custom_field_ids``. + BACKFILL_CREATIVE_CUSTOM_FIELD_9_OPTION_ID (20009): + Custom field option ID for Backfill creative with custom + field ID equal to the ID in index 9 of + ``ReportDefinition.creative_custom_field_ids``. + BACKFILL_CREATIVE_CUSTOM_FIELD_10_OPTION_ID (20010): + Custom field option ID for Backfill creative with custom + field ID equal to the ID in index 10 of + ``ReportDefinition.creative_custom_field_ids``. + BACKFILL_CREATIVE_CUSTOM_FIELD_11_OPTION_ID (20011): + Custom field option ID for Backfill creative with custom + field ID equal to the ID in index 11 of + ``ReportDefinition.creative_custom_field_ids``. + BACKFILL_CREATIVE_CUSTOM_FIELD_12_OPTION_ID (20012): + Custom field option ID for Backfill creative with custom + field ID equal to the ID in index 12 of + ``ReportDefinition.creative_custom_field_ids``. + BACKFILL_CREATIVE_CUSTOM_FIELD_13_OPTION_ID (20013): + Custom field option ID for Backfill creative with custom + field ID equal to the ID in index 13 of + ``ReportDefinition.creative_custom_field_ids``. + BACKFILL_CREATIVE_CUSTOM_FIELD_14_OPTION_ID (20014): + Custom field option ID for Backfill creative with custom + field ID equal to the ID in index 14 of + ``ReportDefinition.creative_custom_field_ids``. + BACKFILL_CREATIVE_CUSTOM_FIELD_0_VALUE (21000): + Custom field value for Backfill creative with custom field + ID equal to the ID in index 0 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 0 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_CREATIVE_CUSTOM_FIELD_1_VALUE (21001): + Custom field value for Backfill creative with custom field + ID equal to the ID in index 1 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 1 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_CREATIVE_CUSTOM_FIELD_2_VALUE (21002): + Custom field value for Backfill creative with custom field + ID equal to the ID in index 2 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 2 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_CREATIVE_CUSTOM_FIELD_3_VALUE (21003): + Custom field value for Backfill creative with custom field + ID equal to the ID in index 3 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 3 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_CREATIVE_CUSTOM_FIELD_4_VALUE (21004): + Custom field value for Backfill creative with custom field + ID equal to the ID in index 4 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 4 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_CREATIVE_CUSTOM_FIELD_5_VALUE (21005): + Custom field value for Backfill creative with custom field + ID equal to the ID in index 5 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 5 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_CREATIVE_CUSTOM_FIELD_6_VALUE (21006): + Custom field value for Backfill creative with custom field + ID equal to the ID in index 6 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 6 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_CREATIVE_CUSTOM_FIELD_7_VALUE (21007): + Custom field value for Backfill creative with custom field + ID equal to the ID in index 7 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 7 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_CREATIVE_CUSTOM_FIELD_8_VALUE (21008): + Custom field value for Backfill creative with custom field + ID equal to the ID in index 8 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 8 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_CREATIVE_CUSTOM_FIELD_9_VALUE (21009): + Custom field value for Backfill creative with custom field + ID equal to the ID in index 9 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 9 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_CREATIVE_CUSTOM_FIELD_10_VALUE (21010): + Custom field value for Backfill creative with custom field + ID equal to the ID in index 10 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 10 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_CREATIVE_CUSTOM_FIELD_11_VALUE (21011): + Custom field value for Backfill creative with custom field + ID equal to the ID in index 11 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 11 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_CREATIVE_CUSTOM_FIELD_12_VALUE (21012): + Custom field value for Backfill creative with custom field + ID equal to the ID in index 12 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 12 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_CREATIVE_CUSTOM_FIELD_13_VALUE (21013): + Custom field value for Backfill creative with custom field + ID equal to the ID in index 13 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 13 is of type ``STRING`` or ``DROPDOWN``. + BACKFILL_CREATIVE_CUSTOM_FIELD_14_VALUE (21014): + Custom field value for Backfill creative with custom field + ID equal to the ID in index 14 of + ``ReportDefinition.creative_custom_field_ids``. Treats the + value as a string. Can only be used if the custom field at + index 14 is of type ``STRING`` or ``DROPDOWN``. + CUSTOM_DIMENSION_0_VALUE_ID (100000): + Custom Dimension Value ID for Custom Dimension with key + equal to the key in index 0 of + ``ReportDefinition.custom_dimension_key_ids``. + CUSTOM_DIMENSION_1_VALUE_ID (100001): + Custom Dimension Value ID for Custom Dimension with key + equal to the key in index 1 of + ``ReportDefinition.custom_dimension_key_ids``. + CUSTOM_DIMENSION_2_VALUE_ID (100002): + Custom Dimension Value ID for Custom Dimension with key + equal to the key in index 2 of + ``ReportDefinition.custom_dimension_key_ids``. + CUSTOM_DIMENSION_3_VALUE_ID (100003): + Custom Dimension Value ID for Custom Dimension with key + equal to the key in index 3 of + ``ReportDefinition.custom_dimension_key_ids``. + CUSTOM_DIMENSION_4_VALUE_ID (100004): + Custom Dimension Value ID for Custom Dimension with key + equal to the key in index 4 of + ``ReportDefinition.custom_dimension_key_ids``. + CUSTOM_DIMENSION_5_VALUE_ID (100005): + Custom Dimension Value ID for Custom Dimension with key + equal to the key in index 5 of + ``ReportDefinition.custom_dimension_key_ids``. + CUSTOM_DIMENSION_6_VALUE_ID (100006): + Custom Dimension Value ID for Custom Dimension with key + equal to the key in index 6 of + ``ReportDefinition.custom_dimension_key_ids``. + CUSTOM_DIMENSION_7_VALUE_ID (100007): + Custom Dimension Value ID for Custom Dimension with key + equal to the key in index 9 of + ``ReportDefinition.custom_dimension_key_ids``. + CUSTOM_DIMENSION_8_VALUE_ID (100008): + Custom Dimension Value ID for Custom Dimension with key + equal to the key in index 8 of + ``ReportDefinition.custom_dimension_key_ids``. + CUSTOM_DIMENSION_9_VALUE_ID (100009): + Custom Dimension Value ID for Custom Dimension with key + equal to the key in index 9 of + ``ReportDefinition.custom_dimension_key_ids``. + CUSTOM_DIMENSION_0_VALUE (101000): + Custom Dimension Value name for Custom Dimension with key + equal to the ID in index 0 of + ``ReportDefinition.custom_dimension_key_ids``. + CUSTOM_DIMENSION_1_VALUE (101001): + Custom Dimension Value name for Custom Dimension with key + equal to the ID in index 1 of + ``ReportDefinition.custom_dimension_key_ids``. + CUSTOM_DIMENSION_2_VALUE (101002): + Custom Dimension Value name for Custom Dimension with key + equal to the ID in index 2 of + ``ReportDefinition.custom_dimension_key_ids``. + CUSTOM_DIMENSION_3_VALUE (101003): + Custom Dimension Value name for Custom Dimension with key + equal to the ID in index 3 of + ``ReportDefinition.custom_dimension_key_ids``. + CUSTOM_DIMENSION_4_VALUE (101004): + Custom Dimension Value name for Custom Dimension with key + equal to the ID in index 4 of + ``ReportDefinition.custom_dimension_key_ids``. + CUSTOM_DIMENSION_5_VALUE (101005): + Custom Dimension Value name for Custom Dimension with key + equal to the ID in index 5 of + ``ReportDefinition.custom_dimension_key_ids``. + CUSTOM_DIMENSION_6_VALUE (101006): + Custom Dimension Value name for Custom Dimension with key + equal to the ID in index 6 of + ``ReportDefinition.custom_dimension_key_ids``. + CUSTOM_DIMENSION_7_VALUE (101007): + Custom Dimension Value name for Custom Dimension with key + equal to the ID in index 7 of + ``ReportDefinition.custom_dimension_key_ids``. + CUSTOM_DIMENSION_8_VALUE (101008): + Custom Dimension Value name for Custom Dimension with key + equal to the ID in index 8 of + ``ReportDefinition.custom_dimension_key_ids``. + CUSTOM_DIMENSION_9_VALUE (101009): + Custom Dimension Value name for Custom Dimension with key + equal to the ID in index 9 of + ``ReportDefinition.custom_dimension_key_ids``. + """ + _pb_options = {"allow_alias": True} + DIMENSION_UNSPECIFIED = 0 + ACTIVE_VIEW_MEASUREMENT_SOURCE = 575 + ACTIVE_VIEW_MEASUREMENT_SOURCE_NAME = 576 + ADVERTISER_CREDIT_STATUS = 475 + ADVERTISER_CREDIT_STATUS_NAME = 476 + ADVERTISER_DOMAIN_NAME = 242 + ADVERTISER_EXTERNAL_ID = 228 + ADVERTISER_ID = 131 + ADVERTISER_LABELS = 230 + ADVERTISER_LABEL_IDS = 229 + ADVERTISER_NAME = 132 + ADVERTISER_PRIMARY_CONTACT = 227 + ADVERTISER_STATUS = 471 + ADVERTISER_STATUS_NAME = 472 + ADVERTISER_TYPE = 473 + ADVERTISER_TYPE_NAME = 474 + ADVERTISER_VERTICAL = 580 + ADX_PRODUCT = 499 + ADX_PRODUCT_NAME = 500 + AD_EXPERIENCES_TYPE = 641 + AD_EXPERIENCES_TYPE_NAME = 642 + AD_LOCATION = 390 + AD_LOCATION_NAME = 391 + AD_TECHNOLOGY_PROVIDER_DOMAIN = 620 + AD_TECHNOLOGY_PROVIDER_ID = 621 + AD_TECHNOLOGY_PROVIDER_NAME = 622 + AD_TYPE = 497 + AD_TYPE_NAME = 498 + AD_UNIT_CODE = 64 + AD_UNIT_CODE_LEVEL_1 = 65 + AD_UNIT_CODE_LEVEL_10 = 74 + AD_UNIT_CODE_LEVEL_11 = 75 + AD_UNIT_CODE_LEVEL_12 = 76 + AD_UNIT_CODE_LEVEL_13 = 77 + AD_UNIT_CODE_LEVEL_14 = 78 + AD_UNIT_CODE_LEVEL_15 = 79 + AD_UNIT_CODE_LEVEL_16 = 80 + AD_UNIT_CODE_LEVEL_2 = 66 + AD_UNIT_CODE_LEVEL_3 = 67 + AD_UNIT_CODE_LEVEL_4 = 68 + AD_UNIT_CODE_LEVEL_5 = 69 + AD_UNIT_CODE_LEVEL_6 = 70 + AD_UNIT_CODE_LEVEL_7 = 71 + AD_UNIT_CODE_LEVEL_8 = 72 + AD_UNIT_CODE_LEVEL_9 = 73 + AD_UNIT_ID = 25 + AD_UNIT_ID_ALL_LEVEL = 27 + AD_UNIT_ID_LEVEL_1 = 30 + AD_UNIT_ID_LEVEL_10 = 48 + AD_UNIT_ID_LEVEL_11 = 50 + AD_UNIT_ID_LEVEL_12 = 52 + AD_UNIT_ID_LEVEL_13 = 54 + AD_UNIT_ID_LEVEL_14 = 56 + AD_UNIT_ID_LEVEL_15 = 58 + AD_UNIT_ID_LEVEL_16 = 60 + AD_UNIT_ID_LEVEL_2 = 32 + AD_UNIT_ID_LEVEL_3 = 34 + AD_UNIT_ID_LEVEL_4 = 36 + AD_UNIT_ID_LEVEL_5 = 38 + AD_UNIT_ID_LEVEL_6 = 40 + AD_UNIT_ID_LEVEL_7 = 42 + AD_UNIT_ID_LEVEL_8 = 44 + AD_UNIT_ID_LEVEL_9 = 46 + AD_UNIT_ID_TOP_LEVEL = 142 + AD_UNIT_NAME = 26 + AD_UNIT_NAME_ALL_LEVEL = 29 + AD_UNIT_NAME_LEVEL_1 = 31 + AD_UNIT_NAME_LEVEL_10 = 49 + AD_UNIT_NAME_LEVEL_11 = 51 + AD_UNIT_NAME_LEVEL_12 = 53 + AD_UNIT_NAME_LEVEL_13 = 55 + AD_UNIT_NAME_LEVEL_14 = 57 + AD_UNIT_NAME_LEVEL_15 = 59 + AD_UNIT_NAME_LEVEL_16 = 61 + AD_UNIT_NAME_LEVEL_2 = 33 + AD_UNIT_NAME_LEVEL_3 = 35 + AD_UNIT_NAME_LEVEL_4 = 37 + AD_UNIT_NAME_LEVEL_5 = 39 + AD_UNIT_NAME_LEVEL_6 = 41 + AD_UNIT_NAME_LEVEL_7 = 43 + AD_UNIT_NAME_LEVEL_8 = 45 + AD_UNIT_NAME_LEVEL_9 = 47 + AD_UNIT_NAME_TOP_LEVEL = 143 + AD_UNIT_REWARD_AMOUNT = 63 + AD_UNIT_REWARD_TYPE = 62 + AD_UNIT_STATUS = 206 + AD_UNIT_STATUS_NAME = 207 + AGENCY_LEVEL_1_ID = 565 + AGENCY_LEVEL_1_NAME = 566 + AGENCY_LEVEL_2_ID = 567 + AGENCY_LEVEL_2_NAME = 568 + AGENCY_LEVEL_3_ID = 569 + AGENCY_LEVEL_3_NAME = 570 + AGE_BRACKET = 508 + AGE_BRACKET_NAME = 582 + APP_TRACKING_TRANSPARENCY_CONSENT_STATUS = 442 + APP_TRACKING_TRANSPARENCY_CONSENT_STATUS_NAME = 443 + APP_VERSION = 392 + AUCTION_PACKAGE_DEAL = 579 + AUCTION_PACKAGE_DEAL_ID = 571 + AUDIENCE_SEGMENT_ID_TARGETED = 584 + AUDIENCE_SEGMENT_TARGETED = 585 + AUTO_REFRESHED_TRAFFIC = 421 + AUTO_REFRESHED_TRAFFIC_NAME = 422 + BIDDER_ENCRYPTED_ID = 493 + BIDDER_NAME = 494 + BID_RANGE = 679 + BID_REJECTION_REASON = 599 + BID_REJECTION_REASON_NAME = 600 + BRANDING_TYPE = 383 + BRANDING_TYPE_NAME = 384 + BROWSER_CATEGORY = 119 + BROWSER_CATEGORY_NAME = 120 + BROWSER_ID = 235 + BROWSER_NAME = 236 + BUYER_NETWORK_ID = 448 + BUYER_NETWORK_NAME = 449 + CALLOUT_STATUS_CATEGORY = 588 + CALLOUT_STATUS_CATEGORY_NAME = 589 + CARRIER_ID = 369 + CARRIER_NAME = 368 + CHANNEL = 501 + CHILD_NETWORK_CODE = 542 + CHILD_NETWORK_ID = 544 + CHILD_PARTNER_NAME = 543 + CITY_ID = 459 + CITY_NAME = 452 + CLASSIFIED_ADVERTISER_ID = 133 + CLASSIFIED_ADVERTISER_NAME = 134 + CLASSIFIED_BRAND_ID = 243 + CLASSIFIED_BRAND_NAME = 244 + CONTENT_CMS_NAME = 643 + CONTENT_CMS_VIDEO_ID = 644 + CONTENT_ID = 246 + CONTENT_MAPPING_PRESENCE = 731 + CONTENT_MAPPING_PRESENCE_NAME = 732 + CONTENT_NAME = 247 + CONTINENT = 469 + CONTINENT_NAME = 470 + COUNTRY_CODE = 466 + COUNTRY_ID = 11 + COUNTRY_NAME = 12 + CREATIVE_BILLING_TYPE = 366 + CREATIVE_BILLING_TYPE_NAME = 367 + CREATIVE_CLICK_THROUGH_URL = 174 + CREATIVE_ID = 138 + CREATIVE_NAME = 139 + CREATIVE_POLICIES_FILTERING = 711 + CREATIVE_POLICIES_FILTERING_NAME = 712 + CREATIVE_PROTECTIONS_FILTERING = 704 + CREATIVE_PROTECTIONS_FILTERING_NAME = 705 + CREATIVE_SET_ROLE_TYPE = 686 + CREATIVE_SET_ROLE_TYPE_NAME = 687 + CREATIVE_TECHNOLOGY = 148 + CREATIVE_TECHNOLOGY_NAME = 149 + CREATIVE_THIRD_PARTY_VENDOR = 361 + CREATIVE_TYPE = 344 + CREATIVE_TYPE_NAME = 345 + CREATIVE_VENDOR_ID = 706 + CREATIVE_VENDOR_NAME = 707 + CREATIVE_VIDEO_REDIRECT_THIRD_PARTY = 562 + CURATOR_ID = 572 + CURATOR_NAME = 573 + CUSTOM_EVENT_ID = 737 + CUSTOM_EVENT_NAME = 735 + CUSTOM_EVENT_TYPE = 736 + CUSTOM_EVENT_TYPE_NAME = 738 + CUSTOM_SPOT_ID = 423 + CUSTOM_SPOT_NAME = 424 + DATE = 3 + DAY_OF_WEEK = 4 + DEAL_BUYER_ID = 240 + DEAL_BUYER_NAME = 241 + DEAL_ID = 436 + DEAL_NAME = 437 + DELIVERED_SECURE_SIGNAL_ID = 309 + DELIVERED_SECURE_SIGNAL_NAME = 310 + DEMAND_CHANNEL = 9 + DEMAND_CHANNEL_NAME = 10 + DEMAND_SOURCE = 592 + DEMAND_SOURCE_NAME = 593 + DEMAND_SUBCHANNEL = 22 + DEMAND_SUBCHANNEL_NAME = 23 + DEVICE = 226 + DEVICE_CATEGORY = 15 + DEVICE_CATEGORY_NAME = 16 + DEVICE_MANUFACTURER_ID = 525 + DEVICE_MANUFACTURER_NAME = 526 + DEVICE_MODEL_ID = 527 + DEVICE_MODEL_NAME = 528 + DEVICE_NAME = 225 + DSP_SEAT_ID = 564 + DYNAMIC_ALLOCATION_TYPE = 502 + DYNAMIC_ALLOCATION_TYPE_NAME = 503 + ESP_DELIVERY = 623 + ESP_DELIVERY_NAME = 624 + ESP_PRESENCE = 625 + ESP_PRESENCE_NAME = 626 + EXCHANGE_BIDDING_DEAL_ID = 715 + EXCHANGE_BIDDING_DEAL_TYPE = 714 + EXCHANGE_BIDDING_DEAL_TYPE_NAME = 723 + EXCHANGE_THIRD_PARTY_COMPANY_ID = 185 + EXCHANGE_THIRD_PARTY_COMPANY_NAME = 186 + FIRST_LOOK_PRICING_RULE_ID = 248 + FIRST_LOOK_PRICING_RULE_NAME = 249 + FIRST_PARTY_ID_STATUS = 404 + FIRST_PARTY_ID_STATUS_NAME = 405 + GENDER = 509 + GENDER_NAME = 583 + GOOGLE_ANALYTICS_STREAM_ID = 519 + GOOGLE_ANALYTICS_STREAM_NAME = 520 + HBT_YIELD_PARTNER_ID = 659 + HBT_YIELD_PARTNER_NAME = 660 + HEADER_BIDDER_INTEGRATION_TYPE = 718 + HEADER_BIDDER_INTEGRATION_TYPE_NAME = 719 + HOUR = 100 + IMPRESSION_COUNTING_METHOD = 577 + IMPRESSION_COUNTING_METHOD_NAME = 578 + INTERACTION_TYPE = 223 + INTERACTION_TYPE_NAME = 224 + INTEREST = 510 + INVENTORY_FORMAT = 17 + INVENTORY_FORMAT_NAME = 18 + INVENTORY_SHARE_ASSIGNMENT_ID = 648 + INVENTORY_SHARE_ASSIGNMENT_NAME = 649 + INVENTORY_SHARE_OUTCOME = 603 + INVENTORY_SHARE_OUTCOME_NAME = 604 + INVENTORY_SHARE_PARTNER_AD_SERVER = 652 + INVENTORY_SHARE_PARTNER_AD_SERVER_NAME = 653 + INVENTORY_SHARE_TARGET_SHARE_PERCENT = 654 + INVENTORY_SHARE_TYPE = 650 + INVENTORY_SHARE_TYPE_NAME = 651 + INVENTORY_TYPE = 19 + INVENTORY_TYPE_NAME = 20 + IS_ADX_DIRECT = 382 + IS_CURATION_TARGETED = 574 + IS_DROPPED = 464 + IS_FIRST_LOOK_DEAL = 401 + KEY_VALUES_ID = 214 + KEY_VALUES_NAME = 215 + LINE_ITEM_AGENCY = 663 + LINE_ITEM_ARCHIVED = 188 + LINE_ITEM_COMPANION_DELIVERY_OPTION = 204 + LINE_ITEM_COMPANION_DELIVERY_OPTION_NAME = 205 + LINE_ITEM_COMPUTED_STATUS = 250 + LINE_ITEM_COMPUTED_STATUS_NAME = 251 + LINE_ITEM_CONTRACTED_QUANTITY = 92 + LINE_ITEM_COST_PER_UNIT = 85 + LINE_ITEM_COST_TYPE = 212 + LINE_ITEM_COST_TYPE_NAME = 213 + LINE_ITEM_CREATIVE_END_DATE = 176 + LINE_ITEM_CREATIVE_ROTATION_TYPE = 189 + LINE_ITEM_CREATIVE_ROTATION_TYPE_NAME = 190 + LINE_ITEM_CREATIVE_START_DATE = 175 + LINE_ITEM_CURRENCY_CODE = 180 + LINE_ITEM_DELIVERY_INDICATOR = 87 + LINE_ITEM_DELIVERY_RATE_TYPE = 191 + LINE_ITEM_DELIVERY_RATE_TYPE_NAME = 192 + LINE_ITEM_DISCOUNT_ABSOLUTE = 195 + LINE_ITEM_DISCOUNT_PERCENTAGE = 196 + LINE_ITEM_END_DATE = 81 + LINE_ITEM_END_DATE_TIME = 83 + LINE_ITEM_ENVIRONMENT_TYPE = 201 + LINE_ITEM_ENVIRONMENT_TYPE_NAME = 202 + LINE_ITEM_EXTERNAL_DEAL_ID = 97 + LINE_ITEM_EXTERNAL_ID = 86 + LINE_ITEM_FREQUENCY_CAP = 256 + LINE_ITEM_ID = 1 + LINE_ITEM_LABELS = 667 + LINE_ITEM_LABEL_IDS = 665 + LINE_ITEM_LAST_MODIFIED_BY_APP = 181 + LINE_ITEM_LIFETIME_CLICKS = 95 + LINE_ITEM_LIFETIME_IMPRESSIONS = 94 + LINE_ITEM_LIFETIME_VIEWABLE_IMPRESSIONS = 96 + LINE_ITEM_MAKEGOOD = 89 + LINE_ITEM_NAME = 2 + LINE_ITEM_NON_CPD_BOOKED_REVENUE = 98 + LINE_ITEM_OPTIMIZABLE = 90 + LINE_ITEM_PO_NUMBER = 669 + LINE_ITEM_PRIMARY_GOAL_TYPE = 210 + LINE_ITEM_PRIMARY_GOAL_TYPE_NAME = 211 + LINE_ITEM_PRIMARY_GOAL_UNITS_ABSOLUTE = 93 + LINE_ITEM_PRIMARY_GOAL_UNITS_PERCENTAGE = 396 + LINE_ITEM_PRIMARY_GOAL_UNIT_TYPE = 208 + LINE_ITEM_PRIMARY_GOAL_UNIT_TYPE_NAME = 209 + LINE_ITEM_PRIORITY = 24 + LINE_ITEM_RESERVATION_STATUS = 304 + LINE_ITEM_RESERVATION_STATUS_NAME = 305 + LINE_ITEM_SALESPERSON = 671 + LINE_ITEM_SECONDARY_SALESPEOPLE = 673 + LINE_ITEM_SECONDARY_TRAFFICKERS = 675 + LINE_ITEM_START_DATE = 82 + LINE_ITEM_START_DATE_TIME = 84 + LINE_ITEM_TRAFFICKER = 677 + LINE_ITEM_TYPE = 193 + LINE_ITEM_TYPE_NAME = 194 + LINE_ITEM_UNLIMITED_END = 187 + LINE_ITEM_VALUE_COST_PER_UNIT = 88 + LINE_ITEM_WEB_PROPERTY_CODE = 179 + MASTER_COMPANION_CREATIVE_ID = 140 + MASTER_COMPANION_CREATIVE_NAME = 141 + MEDIATION_TYPE = 701 + MEDIATION_TYPE_NAME = 754 + MEDIATION_YIELD_PARTNER_ID = 661 + MEDIATION_YIELD_PARTNER_NAME = 662 + METRO_ID = 453 + METRO_NAME = 454 + MOBILE_APP_FREE = 128 + MOBILE_APP_ICON_URL = 129 + MOBILE_APP_ID = 123 + MOBILE_APP_NAME = 127 + MOBILE_APP_OWNERSHIP_STATUS = 311 + MOBILE_APP_OWNERSHIP_STATUS_NAME = 312 + MOBILE_APP_STORE = 125 + MOBILE_APP_STORE_NAME = 245 + MOBILE_INVENTORY_TYPE = 99 + MOBILE_INVENTORY_TYPE_NAME = 21 + MOBILE_RENDERING_SDK = 646 + MOBILE_RENDERING_SDK_NAME = 647 + MOBILE_SDK_MAJOR_VERSION = 692 + MOBILE_SDK_MINOR_VERSION = 693 + MOBILE_SDK_VERSION_NAME = 130 + MONTH_YEAR = 6 + NATIVE_AD_FORMAT_ID = 255 + NATIVE_AD_FORMAT_NAME = 254 + NATIVE_STYLE_ID = 253 + NATIVE_STYLE_NAME = 252 + NO_FILL_REASON_CATEGORY = 586 + NO_FILL_REASON_CATEGORY_NAME = 587 + OPERATING_SYSTEM_CATEGORY = 117 + OPERATING_SYSTEM_CATEGORY_NAME = 118 + OPERATING_SYSTEM_VERSION_ID = 238 + OPERATING_SYSTEM_VERSION_NAME = 237 + OPTIMIZATION_TYPE = 639 + OPTIMIZATION_TYPE_NAME = 640 + ORDER_AGENCY = 150 + ORDER_AGENCY_ID = 151 + ORDER_BOOKED_CPC = 152 + ORDER_BOOKED_CPM = 153 + ORDER_DELIVERY_STATUS = 231 + ORDER_DELIVERY_STATUS_NAME = 239 + ORDER_END_DATE = 154 + ORDER_END_DATE_TIME = 155 + ORDER_EXTERNAL_ID = 156 + ORDER_ID = 7 + ORDER_LABELS = 170 + ORDER_LABEL_IDS = 171 + ORDER_LIFETIME_CLICKS = 158 + ORDER_LIFETIME_IMPRESSIONS = 159 + ORDER_NAME = 8 + ORDER_PO_NUMBER = 160 + ORDER_PROGRAMMATIC = 157 + ORDER_SALESPERSON = 161 + ORDER_SALESPERSON_ID = 629 + ORDER_SECONDARY_SALESPEOPLE = 164 + ORDER_SECONDARY_SALESPEOPLE_ID = 165 + ORDER_SECONDARY_TRAFFICKERS = 166 + ORDER_SECONDARY_TRAFFICKERS_ID = 167 + ORDER_START_DATE = 168 + ORDER_START_DATE_TIME = 169 + ORDER_TRAFFICKER = 162 + ORDER_TRAFFICKER_ID = 163 + ORDER_UNLIMITED_END = 203 + PAGE_PATH = 511 + PAGE_TITLE_AND_SCREEN_CLASS = 512 + PAGE_TITLE_AND_SCREEN_NAME = 513 + PLACEMENT_ID = 113 + PLACEMENT_ID_ALL = 144 + PLACEMENT_NAME = 114 + PLACEMENT_NAME_ALL = 145 + PLACEMENT_STATUS = 362 + PLACEMENT_STATUS_NAME = 364 + PLACEMENT_STATUS_NAME_ALL = 365 + POSTAL_CODE_ID = 455 + POSTAL_CODE_NAME = 456 + PPID_STATUS = 406 + PPID_STATUS_NAME = 407 + PREDICTED_VIEWABILITY_BUCKET = 633 + PREDICTED_VIEWABILITY_BUCKET_NAME = 634 + PRESENTED_SECURE_SIGNAL_ID = 495 + PRESENTED_SECURE_SIGNAL_NAME = 496 + PRIMARY_PERSONALIZATION_ID_TYPE = 408 + PRIMARY_PERSONALIZATION_ID_TYPE_NAME = 409 + PROGRAMMATIC_BUYER_ID = 240 + PROGRAMMATIC_BUYER_NAME = 241 + PROGRAMMATIC_CHANNEL = 13 + PROGRAMMATIC_CHANNEL_NAME = 14 + PUBLISHER_PROVIDED_SIGNALS_ALL_LEVELS_EXTERNAL_CODE = 410 + PUBLISHER_PROVIDED_SIGNALS_ALL_LEVELS_IDS = 546 + PUBLISHER_PROVIDED_SIGNALS_ALL_LEVELS_NAME = 412 + PUBLISHER_PROVIDED_SIGNALS_ALL_LEVELS_TIER = 413 + PUBLISHER_PROVIDED_SIGNALS_ALL_LEVELS_TYPE = 414 + PUBLISHER_PROVIDED_SIGNALS_DELIVERED_EXTERNAL_CODE = 425 + PUBLISHER_PROVIDED_SIGNALS_DELIVERED_IDS = 545 + PUBLISHER_PROVIDED_SIGNALS_DELIVERED_NAME = 427 + PUBLISHER_PROVIDED_SIGNALS_DELIVERED_TIER = 428 + PUBLISHER_PROVIDED_SIGNALS_DELIVERED_TYPE = 429 + PUBLISHER_PROVIDED_SIGNALS_TOP_LEVEL_EXTERNAL_CODE = 415 + PUBLISHER_PROVIDED_SIGNALS_TOP_LEVEL_ID = 416 + PUBLISHER_PROVIDED_SIGNALS_TOP_LEVEL_NAME = 417 + PUBLISHER_PROVIDED_SIGNALS_TOP_LEVEL_TIER = 418 + PUBLISHER_PROVIDED_SIGNALS_TOP_LEVEL_TYPE = 419 + PUBLISHER_PROVIDED_SIGNAL_DATA_PROVIDER_ID = 136 + PUBLISHER_PROVIDED_SIGNAL_DATA_PROVIDER_NAME = 137 + REGION_ID = 457 + REGION_NAME = 458 + REJECTION_CLASS_CATEGORY = 590 + REJECTION_CLASS_CATEGORY_NAME = 591 + RENDERED_CREATIVE_SIZE = 343 + REQUESTED_AD_SIZES = 352 + REQUEST_TYPE = 146 + REQUEST_TYPE_NAME = 147 + SERVER_SIDE_UNWRAPPING_ELIGIBLE = 597 + SERVING_RESTRICTION = 631 + SERVING_RESTRICTION_NAME = 632 + SITE = 387 + TARGETING_ID = 232 + TARGETING_NAME = 233 + TARGETING_TYPE = 385 + TARGETING_TYPE_NAME = 386 + THIRD_PARTY_ID_STATUS = 402 + THIRD_PARTY_ID_STATUS_NAME = 403 + TOPICS_STATUS = 504 + TOPICS_STATUS_NAME = 505 + TOP_PRIVATE_DOMAIN = 444 + TRAFFIC_SOURCE = 388 + TRAFFIC_SOURCE_NAME = 389 + UNIFIED_PRICING_RULE_ID = 393 + UNIFIED_PRICING_RULE_NAME = 394 + URL = 506 + URL_ID = 507 + USER_MESSAGES_ENTITLEMENT_SOURCE = 635 + USER_MESSAGES_ENTITLEMENT_SOURCE_NAME = 636 + USER_MESSAGES_OPERATING_SYSTEM_CRITERIA_ID = 637 + USER_MESSAGES_OPERATING_SYSTEM_CRITERIA_NAME = 638 + VAST_VERSION = 554 + VAST_VERSION_NAME = 555 + VIDEO_AD_BREAK_TYPE = 556 + VIDEO_AD_BREAK_TYPE_NAME = 557 + VIDEO_AD_DURATION = 450 + VIDEO_AD_FORMATS_RULE = 561 + VIDEO_AD_FORMATS_RULE_ID = 560 + VIDEO_AD_REQUEST_DURATION = 558 + VIDEO_AD_REQUEST_DURATION_MIDPOINT_NAME = 751 + VIDEO_AD_REQUEST_DURATION_NAME = 559 + VIDEO_AD_REQUEST_SOURCE = 438 + VIDEO_AD_REQUEST_SOURCE_NAME = 439 + VIDEO_AD_TYPE = 432 + VIDEO_AD_TYPE_NAME = 433 + VIDEO_CONTINUOUS_PLAY_TYPE = 721 + VIDEO_CONTINUOUS_PLAY_TYPE_NAME = 722 + VIDEO_FALLBACK_POSITION = 530 + VIDEO_MEASUREMENT_SOURCE = 601 + VIDEO_MEASUREMENT_SOURCE_NAME = 602 + VIDEO_PLCMT = 172 + VIDEO_PLCMT_NAME = 173 + VIDEO_POSITION_IN_POD = 538 + VIDEO_POSITION_OF_POD = 539 + VIDEO_SDK_VERSION = 440 + VIDEO_SDK_VERSION_NAME = 441 + VIDEO_STITCHER_TYPE = 752 + VIDEO_STITCHER_TYPE_NAME = 753 + WEEK = 5 + YIELD_GROUP_BUYER_NAME = 184 + YIELD_GROUP_BUYER_TAG_NAME = 627 + YIELD_GROUP_ID = 182 + YIELD_GROUP_NAME = 183 + YOUTUBE_AD_DURATION_BUCKET = 430 + YOUTUBE_AD_DURATION_BUCKET_NAME = 431 + YOUTUBE_AD_TYPE = 399 + YOUTUBE_AD_TYPE_NAME = 400 + LINE_ITEM_CUSTOM_FIELD_0_OPTION_ID = 10000 + LINE_ITEM_CUSTOM_FIELD_1_OPTION_ID = 10001 + LINE_ITEM_CUSTOM_FIELD_2_OPTION_ID = 10002 + LINE_ITEM_CUSTOM_FIELD_3_OPTION_ID = 10003 + LINE_ITEM_CUSTOM_FIELD_4_OPTION_ID = 10004 + LINE_ITEM_CUSTOM_FIELD_5_OPTION_ID = 10005 + LINE_ITEM_CUSTOM_FIELD_6_OPTION_ID = 10006 + LINE_ITEM_CUSTOM_FIELD_7_OPTION_ID = 10007 + LINE_ITEM_CUSTOM_FIELD_8_OPTION_ID = 10008 + LINE_ITEM_CUSTOM_FIELD_9_OPTION_ID = 10009 + LINE_ITEM_CUSTOM_FIELD_10_OPTION_ID = 10010 + LINE_ITEM_CUSTOM_FIELD_11_OPTION_ID = 10011 + LINE_ITEM_CUSTOM_FIELD_12_OPTION_ID = 10012 + LINE_ITEM_CUSTOM_FIELD_13_OPTION_ID = 10013 + LINE_ITEM_CUSTOM_FIELD_14_OPTION_ID = 10014 + LINE_ITEM_CUSTOM_FIELD_0_VALUE = 11000 + LINE_ITEM_CUSTOM_FIELD_1_VALUE = 11001 + LINE_ITEM_CUSTOM_FIELD_2_VALUE = 11002 + LINE_ITEM_CUSTOM_FIELD_3_VALUE = 11003 + LINE_ITEM_CUSTOM_FIELD_4_VALUE = 11004 + LINE_ITEM_CUSTOM_FIELD_5_VALUE = 11005 + LINE_ITEM_CUSTOM_FIELD_6_VALUE = 11006 + LINE_ITEM_CUSTOM_FIELD_7_VALUE = 11007 + LINE_ITEM_CUSTOM_FIELD_8_VALUE = 11008 + LINE_ITEM_CUSTOM_FIELD_9_VALUE = 11009 + LINE_ITEM_CUSTOM_FIELD_10_VALUE = 11010 + LINE_ITEM_CUSTOM_FIELD_11_VALUE = 11011 + LINE_ITEM_CUSTOM_FIELD_12_VALUE = 11012 + LINE_ITEM_CUSTOM_FIELD_13_VALUE = 11013 + LINE_ITEM_CUSTOM_FIELD_14_VALUE = 11014 + ORDER_CUSTOM_FIELD_0_OPTION_ID = 12000 + ORDER_CUSTOM_FIELD_1_OPTION_ID = 12001 + ORDER_CUSTOM_FIELD_2_OPTION_ID = 12002 + ORDER_CUSTOM_FIELD_3_OPTION_ID = 12003 + ORDER_CUSTOM_FIELD_4_OPTION_ID = 12004 + ORDER_CUSTOM_FIELD_5_OPTION_ID = 12005 + ORDER_CUSTOM_FIELD_6_OPTION_ID = 12006 + ORDER_CUSTOM_FIELD_7_OPTION_ID = 12007 + ORDER_CUSTOM_FIELD_8_OPTION_ID = 12008 + ORDER_CUSTOM_FIELD_9_OPTION_ID = 12009 + ORDER_CUSTOM_FIELD_10_OPTION_ID = 12010 + ORDER_CUSTOM_FIELD_11_OPTION_ID = 12011 + ORDER_CUSTOM_FIELD_12_OPTION_ID = 12012 + ORDER_CUSTOM_FIELD_13_OPTION_ID = 12013 + ORDER_CUSTOM_FIELD_14_OPTION_ID = 12014 + ORDER_CUSTOM_FIELD_0_VALUE = 13000 + ORDER_CUSTOM_FIELD_1_VALUE = 13001 + ORDER_CUSTOM_FIELD_2_VALUE = 13002 + ORDER_CUSTOM_FIELD_3_VALUE = 13003 + ORDER_CUSTOM_FIELD_4_VALUE = 13004 + ORDER_CUSTOM_FIELD_5_VALUE = 13005 + ORDER_CUSTOM_FIELD_6_VALUE = 13006 + ORDER_CUSTOM_FIELD_7_VALUE = 13007 + ORDER_CUSTOM_FIELD_8_VALUE = 13008 + ORDER_CUSTOM_FIELD_9_VALUE = 13009 + ORDER_CUSTOM_FIELD_10_VALUE = 13010 + ORDER_CUSTOM_FIELD_11_VALUE = 13011 + ORDER_CUSTOM_FIELD_12_VALUE = 13012 + ORDER_CUSTOM_FIELD_13_VALUE = 13013 + ORDER_CUSTOM_FIELD_14_VALUE = 13014 + CREATIVE_CUSTOM_FIELD_0_OPTION_ID = 14000 + CREATIVE_CUSTOM_FIELD_1_OPTION_ID = 14001 + CREATIVE_CUSTOM_FIELD_2_OPTION_ID = 14002 + CREATIVE_CUSTOM_FIELD_3_OPTION_ID = 14003 + CREATIVE_CUSTOM_FIELD_4_OPTION_ID = 14004 + CREATIVE_CUSTOM_FIELD_5_OPTION_ID = 14005 + CREATIVE_CUSTOM_FIELD_6_OPTION_ID = 14006 + CREATIVE_CUSTOM_FIELD_7_OPTION_ID = 14007 + CREATIVE_CUSTOM_FIELD_8_OPTION_ID = 14008 + CREATIVE_CUSTOM_FIELD_9_OPTION_ID = 14009 + CREATIVE_CUSTOM_FIELD_10_OPTION_ID = 14010 + CREATIVE_CUSTOM_FIELD_11_OPTION_ID = 14011 + CREATIVE_CUSTOM_FIELD_12_OPTION_ID = 14012 + CREATIVE_CUSTOM_FIELD_13_OPTION_ID = 14013 + CREATIVE_CUSTOM_FIELD_14_OPTION_ID = 14014 + CREATIVE_CUSTOM_FIELD_0_VALUE = 15000 + CREATIVE_CUSTOM_FIELD_1_VALUE = 15001 + CREATIVE_CUSTOM_FIELD_2_VALUE = 15002 + CREATIVE_CUSTOM_FIELD_3_VALUE = 15003 + CREATIVE_CUSTOM_FIELD_4_VALUE = 15004 + CREATIVE_CUSTOM_FIELD_5_VALUE = 15005 + CREATIVE_CUSTOM_FIELD_6_VALUE = 15006 + CREATIVE_CUSTOM_FIELD_7_VALUE = 15007 + CREATIVE_CUSTOM_FIELD_8_VALUE = 15008 + CREATIVE_CUSTOM_FIELD_9_VALUE = 15009 + CREATIVE_CUSTOM_FIELD_10_VALUE = 15010 + CREATIVE_CUSTOM_FIELD_11_VALUE = 15011 + CREATIVE_CUSTOM_FIELD_12_VALUE = 15012 + CREATIVE_CUSTOM_FIELD_13_VALUE = 15013 + CREATIVE_CUSTOM_FIELD_14_VALUE = 15014 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_0_OPTION_ID = 16000 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_1_OPTION_ID = 16001 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_2_OPTION_ID = 16002 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_3_OPTION_ID = 16003 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_4_OPTION_ID = 16004 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_5_OPTION_ID = 16005 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_6_OPTION_ID = 16006 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_7_OPTION_ID = 16007 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_8_OPTION_ID = 16008 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_9_OPTION_ID = 16009 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_10_OPTION_ID = 16010 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_11_OPTION_ID = 16011 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_12_OPTION_ID = 16012 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_13_OPTION_ID = 16013 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_14_OPTION_ID = 16014 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_0_VALUE = 17000 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_1_VALUE = 17001 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_2_VALUE = 17002 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_3_VALUE = 17003 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_4_VALUE = 17004 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_5_VALUE = 17005 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_6_VALUE = 17006 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_7_VALUE = 17007 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_8_VALUE = 17008 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_9_VALUE = 17009 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_10_VALUE = 17010 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_11_VALUE = 17011 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_12_VALUE = 17012 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_13_VALUE = 17013 + BACKFILL_LINE_ITEM_CUSTOM_FIELD_14_VALUE = 17014 + BACKFILL_ORDER_CUSTOM_FIELD_0_OPTION_ID = 18000 + BACKFILL_ORDER_CUSTOM_FIELD_1_OPTION_ID = 18001 + BACKFILL_ORDER_CUSTOM_FIELD_2_OPTION_ID = 18002 + BACKFILL_ORDER_CUSTOM_FIELD_3_OPTION_ID = 18003 + BACKFILL_ORDER_CUSTOM_FIELD_4_OPTION_ID = 18004 + BACKFILL_ORDER_CUSTOM_FIELD_5_OPTION_ID = 18005 + BACKFILL_ORDER_CUSTOM_FIELD_6_OPTION_ID = 18006 + BACKFILL_ORDER_CUSTOM_FIELD_7_OPTION_ID = 18007 + BACKFILL_ORDER_CUSTOM_FIELD_8_OPTION_ID = 18008 + BACKFILL_ORDER_CUSTOM_FIELD_9_OPTION_ID = 18009 + BACKFILL_ORDER_CUSTOM_FIELD_10_OPTION_ID = 18010 + BACKFILL_ORDER_CUSTOM_FIELD_11_OPTION_ID = 18011 + BACKFILL_ORDER_CUSTOM_FIELD_12_OPTION_ID = 18012 + BACKFILL_ORDER_CUSTOM_FIELD_13_OPTION_ID = 18013 + BACKFILL_ORDER_CUSTOM_FIELD_14_OPTION_ID = 18014 + BACKFILL_ORDER_CUSTOM_FIELD_0_VALUE = 19000 + BACKFILL_ORDER_CUSTOM_FIELD_1_VALUE = 19001 + BACKFILL_ORDER_CUSTOM_FIELD_2_VALUE = 19002 + BACKFILL_ORDER_CUSTOM_FIELD_3_VALUE = 19003 + BACKFILL_ORDER_CUSTOM_FIELD_4_VALUE = 19004 + BACKFILL_ORDER_CUSTOM_FIELD_5_VALUE = 19005 + BACKFILL_ORDER_CUSTOM_FIELD_6_VALUE = 19006 + BACKFILL_ORDER_CUSTOM_FIELD_7_VALUE = 19007 + BACKFILL_ORDER_CUSTOM_FIELD_8_VALUE = 19008 + BACKFILL_ORDER_CUSTOM_FIELD_9_VALUE = 19009 + BACKFILL_ORDER_CUSTOM_FIELD_10_VALUE = 19010 + BACKFILL_ORDER_CUSTOM_FIELD_11_VALUE = 19011 + BACKFILL_ORDER_CUSTOM_FIELD_12_VALUE = 19012 + BACKFILL_ORDER_CUSTOM_FIELD_13_VALUE = 19013 + BACKFILL_ORDER_CUSTOM_FIELD_14_VALUE = 19014 + BACKFILL_CREATIVE_CUSTOM_FIELD_0_OPTION_ID = 20000 + BACKFILL_CREATIVE_CUSTOM_FIELD_1_OPTION_ID = 20001 + BACKFILL_CREATIVE_CUSTOM_FIELD_2_OPTION_ID = 20002 + BACKFILL_CREATIVE_CUSTOM_FIELD_3_OPTION_ID = 20003 + BACKFILL_CREATIVE_CUSTOM_FIELD_4_OPTION_ID = 20004 + BACKFILL_CREATIVE_CUSTOM_FIELD_5_OPTION_ID = 20005 + BACKFILL_CREATIVE_CUSTOM_FIELD_6_OPTION_ID = 20006 + BACKFILL_CREATIVE_CUSTOM_FIELD_7_OPTION_ID = 20007 + BACKFILL_CREATIVE_CUSTOM_FIELD_8_OPTION_ID = 20008 + BACKFILL_CREATIVE_CUSTOM_FIELD_9_OPTION_ID = 20009 + BACKFILL_CREATIVE_CUSTOM_FIELD_10_OPTION_ID = 20010 + BACKFILL_CREATIVE_CUSTOM_FIELD_11_OPTION_ID = 20011 + BACKFILL_CREATIVE_CUSTOM_FIELD_12_OPTION_ID = 20012 + BACKFILL_CREATIVE_CUSTOM_FIELD_13_OPTION_ID = 20013 + BACKFILL_CREATIVE_CUSTOM_FIELD_14_OPTION_ID = 20014 + BACKFILL_CREATIVE_CUSTOM_FIELD_0_VALUE = 21000 + BACKFILL_CREATIVE_CUSTOM_FIELD_1_VALUE = 21001 + BACKFILL_CREATIVE_CUSTOM_FIELD_2_VALUE = 21002 + BACKFILL_CREATIVE_CUSTOM_FIELD_3_VALUE = 21003 + BACKFILL_CREATIVE_CUSTOM_FIELD_4_VALUE = 21004 + BACKFILL_CREATIVE_CUSTOM_FIELD_5_VALUE = 21005 + BACKFILL_CREATIVE_CUSTOM_FIELD_6_VALUE = 21006 + BACKFILL_CREATIVE_CUSTOM_FIELD_7_VALUE = 21007 + BACKFILL_CREATIVE_CUSTOM_FIELD_8_VALUE = 21008 + BACKFILL_CREATIVE_CUSTOM_FIELD_9_VALUE = 21009 + BACKFILL_CREATIVE_CUSTOM_FIELD_10_VALUE = 21010 + BACKFILL_CREATIVE_CUSTOM_FIELD_11_VALUE = 21011 + BACKFILL_CREATIVE_CUSTOM_FIELD_12_VALUE = 21012 + BACKFILL_CREATIVE_CUSTOM_FIELD_13_VALUE = 21013 + BACKFILL_CREATIVE_CUSTOM_FIELD_14_VALUE = 21014 + CUSTOM_DIMENSION_0_VALUE_ID = 100000 + CUSTOM_DIMENSION_1_VALUE_ID = 100001 + CUSTOM_DIMENSION_2_VALUE_ID = 100002 + CUSTOM_DIMENSION_3_VALUE_ID = 100003 + CUSTOM_DIMENSION_4_VALUE_ID = 100004 + CUSTOM_DIMENSION_5_VALUE_ID = 100005 + CUSTOM_DIMENSION_6_VALUE_ID = 100006 + CUSTOM_DIMENSION_7_VALUE_ID = 100007 + CUSTOM_DIMENSION_8_VALUE_ID = 100008 + CUSTOM_DIMENSION_9_VALUE_ID = 100009 + CUSTOM_DIMENSION_0_VALUE = 101000 + CUSTOM_DIMENSION_1_VALUE = 101001 + CUSTOM_DIMENSION_2_VALUE = 101002 + CUSTOM_DIMENSION_3_VALUE = 101003 + CUSTOM_DIMENSION_4_VALUE = 101004 + CUSTOM_DIMENSION_5_VALUE = 101005 + CUSTOM_DIMENSION_6_VALUE = 101006 + CUSTOM_DIMENSION_7_VALUE = 101007 + CUSTOM_DIMENSION_8_VALUE = 101008 + CUSTOM_DIMENSION_9_VALUE = 101009 + + class Metric(proto.Enum): + r"""Reporting metrics. + + Values: + METRIC_UNSPECIFIED (0): + Default value. This value is unused. + ACTIVE_USERS (223): + The number of people who engaged with your site or app in + the specified date range from Google Analytics. + + Corresponds to "Active users" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + ACTIVE_VIEW_AUDIBLE_AT_START_PERCENT (445): + Number of impressions with unmuted playback at start. + + Corresponds to "Active View % audible at start" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ACTIVE_VIEW_AUDIBLE_IMPRESSIONS (659): + Total Active View audible impressions + + Corresponds to "Total Active View audible impressions" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + ACTIVE_VIEW_AUDIBLE_THROUGH_COMPLETION_PERCENT (446): + Number of impressions with unmuted playback through the + entire stream. + + Corresponds to "Active View % audible through completion" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ACTIVE_VIEW_AUDIBLE_THROUGH_FIRST_QUARTILE_PERCENT (447): + Number of impressions with unmuted playback through at least + 25%. + + Corresponds to "Active View % audible through first + quartile" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ACTIVE_VIEW_AUDIBLE_THROUGH_MIDPOINT_PERCENT (448): + Number of impressions with unmuted playback through at least + 50%. + + Corresponds to "Active View % audible through midpoint" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ACTIVE_VIEW_AUDIBLE_THROUGH_THIRD_QUARTILE_PERCENT (449): + Number of impressions with unmuted playback through at least + 75%. + + Corresponds to "Active View % audible through third + quartile" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ACTIVE_VIEW_AUDIO_ENABLED_IMPRESSIONS (660): + Total Active View audio enabled impressions + + Corresponds to "Total Active View audio eligible + impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + ACTIVE_VIEW_AUDIO_MEASURABLE_IMPRESSIONS (661): + Total Active View audio measurable impressions + + Corresponds to "Total Active View audio measurable + impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + ACTIVE_VIEW_AVERAGE_VIEWABLE_TIME (61): + Active View total average time in seconds that specific + impressions are reported as being viewable. + + Corresponds to "Total Active View average viewable time + (seconds)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + ACTIVE_VIEW_ELIGIBLE_IMPRESSIONS (58): + Total number of impressions that were eligible to measure + viewability. + + Corresponds to "Total Active View eligible impressions" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + ACTIVE_VIEW_EVER_AUDIBLE_BACKGROUNDED_PERCENT (450): + Number of impressions where the ad player is in the + background at any point during playback with volume > 0. + + Corresponds to "Active View % ever audible while + backgrounded" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ACTIVE_VIEW_EVER_AUDIBLE_PERCENT (451): + Number of impressions where volume > 0 at any point. + + Corresponds to "Active View % ever audible" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ACTIVE_VIEW_EVER_BACKGROUNDED_PERCENT (452): + Number of impressions where the ad player is in the + background at any point during playback. + + Corresponds to "Active View % ever backgrounded" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ACTIVE_VIEW_EVER_MUTED_PERCENT (453): + Number of impressions where volume = 0 at any point. + + Corresponds to "Active View % ever muted" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ACTIVE_VIEW_IMPRESSIONS_AUDIBLE_AND_VISIBLIE_AT_COMPLETION (411): + The number of measurable impressions that were played to + video completion, and also audible and visible at the time + of completion. + + Corresponds to "Total Active View impressions audible and + visible at completion" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + ACTIVE_VIEW_MEASURABLE_IMPRESSIONS (57): + The total number of impressions that were sampled and + measured by active view. + + Corresponds to "Total Active View measurable impressions" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + ACTIVE_VIEW_MEASURABLE_IMPRESSIONS_RATE (60): + The percentage of total impressions that were measurable by + active view (out of all the total impressions sampled for + active view). + + Corresponds to "Total Active View % measurable impressions" + in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ACTIVE_VIEW_NON_MEASURABLE_IMPRESSIONS (662): + Total Active View non-measurable impressions + + Corresponds to "Total Active View non-measurable + impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + ACTIVE_VIEW_NON_VIEWABLE_IMPRESSIONS (663): + Total Active View non-viewable impressions + + Corresponds to "Total Active View non-viewable impressions" + in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + ACTIVE_VIEW_NON_VIEWABLE_IMPRESSIONS_DISTRIBUTION (664): + Total Active View non-viewable impressions distribution + + Corresponds to "Total Active View non-viewable impression + distribution" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ACTIVE_VIEW_PERCENT_AUDIBLE_IMPRESSIONS (665): + Total Active View percent audible impressions + + Corresponds to "Total Active View % audible impressions" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ACTIVE_VIEW_PLUS_MEASURABLE_COUNT (454): + Number of impressions where we were able to collect Active + View+ signals. + + Corresponds to "Active View+ measurable impressions" in the + Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + ACTIVE_VIEW_REVENUE (414): + Revenue generated from Active View impressions. + + Corresponds to "Total Active View revenue" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + ACTIVE_VIEW_UNDETERMINED_IMPRESSIONS_DISTRIBUTION (666): + Total Active View undetermined impressions distribution + + Corresponds to "Total Active View undetermined impression + distribution" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ACTIVE_VIEW_VIEWABLE_IMPRESSIONS (56): + The total number of impressions viewed on the user's screen. + + Corresponds to "Total Active View viewable impressions" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_DISTRIBUTION (667): + Total Active View viewable impressions distribution + + Corresponds to "Total Active View viewable impression + distribution" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_RATE (59): + The percentage of total impressions viewed on the user's + screen (out of the total impressions measurable by active + view). + + Corresponds to "Total Active View % viewable impressions" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ADSENSE_ACTIVE_VIEW_AVERAGE_VIEWABLE_TIME (73): + Active View AdSense average time in seconds that specific + impressions are reported as being viewable. + + Corresponds to "AdSense Active View average viewable time + (seconds)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + ADSENSE_ACTIVE_VIEW_ELIGIBLE_IMPRESSIONS (70): + Total number of impressions delivered by AdSense that were + eligible to measure viewability. + + Corresponds to "AdSense Active View eligible impressions" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + ADSENSE_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS (69): + The number of impressions delivered by AdSense that were + sampled, and measurable by active view. + + Corresponds to "AdSense Active View measurable impressions" + in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + ADSENSE_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS_RATE (72): + The percentage of impressions delivered by AdSense that were + measurable by active view (out of all AdSense impressions + sampled for active view). + + Corresponds to "AdSense Active View % measurable + impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ADSENSE_ACTIVE_VIEW_NON_MEASURABLE_IMPRESSIONS (642): + AdSense Active View non-measurable impressions + + Corresponds to "AdSense Active View non-measurable + impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + ADSENSE_ACTIVE_VIEW_NON_VIEWABLE_IMPRESSIONS (643): + AdSense Active View non-viewable impressions + + Corresponds to "AdSense Active View non-viewable + impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + ADSENSE_ACTIVE_VIEW_NON_VIEWABLE_IMPRESSIONS_DISTRIBUTION (644): + AdSense Active View non-viewable impressions distribution + + Corresponds to "AdSense Active View non-viewable impression + distribution" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ADSENSE_ACTIVE_VIEW_UNDETERMINED_IMPRESSIONS_DISTRIBUTION (645): + AdSense Active View undetermined impressions distribution + + Corresponds to "AdSense Active View undetermined impression + distribution" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ADSENSE_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS (68): + The number of impressions delivered by AdSense viewed on the + user's screen. + + Corresponds to "AdSense Active View viewable impressions" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + ADSENSE_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_DISTRIBUTION (646): + AdSense Active View viewable impressions distribution + + Corresponds to "AdSense Active View viewable impression + distribution" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ADSENSE_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_RATE (71): + The percentage of impressions delivered by AdSense viewed on + the user's screen (out of AdSense impressions measurable by + active view). + + Corresponds to "AdSense Active View % viewable impressions" + in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ADSENSE_AVERAGE_ECPM (26): + The average effective cost-per-thousand-impressions earned + from the ads delivered by AdSense through line item dynamic + allocation. + + Corresponds to "AdSense average eCPM" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + ADSENSE_CLICKS (23): + Number of clicks delivered by AdSense demand channel. + + Corresponds to "AdSense clicks" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + ADSENSE_CTR (24): + The ratio of impressions served by AdSense that resulted in + users clicking on an ad. The clickthrough rate (CTR) is + updated nightly. The AdSense CTR is calculated as: (AdSense + clicks / AdSense impressions). + + Corresponds to "AdSense CTR" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ADSENSE_IMPRESSIONS (22): + Total impressions delivered by AdSense. + + Corresponds to "AdSense impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + ADSENSE_PERCENT_CLICKS (28): + Ratio of clicks delivered by AdSense through line item + dynamic allocation in relation to the total clicks + delivered. + + Corresponds to "AdSense clicks (%)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ADSENSE_PERCENT_IMPRESSIONS (27): + Ratio of impressions delivered by AdSense through line item + dynamic allocation in relation to the total impressions + delivered. + + Corresponds to "AdSense impressions (%)" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ADSENSE_PERCENT_REVENUE (29): + Ratio of revenue generated by AdSense through line item + dynamic allocation in relation to the total revenue. + + Corresponds to "AdSense revenue (%)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ADSENSE_PERCENT_REVENUE_WITHOUT_CPD (30): + Ratio of revenue generated by AdSense through line item + dynamic allocation in relation to the total revenue + (excluding CPD). + + Corresponds to "AdSense revenue w/o CPD (%)" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ADSENSE_RESPONSES_SERVED (41): + The total number of times that an AdSense ad is delivered. + + Corresponds to "AdSense responses served" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + ADSENSE_REVENUE (25): + Revenue generated from AdSense through line item dynamic + allocation, calculated in the network's currency and time + zone. + + Corresponds to "AdSense revenue" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + AD_EXCHANGE_ACTIVE_VIEW_AVERAGE_VIEWABLE_TIME (79): + Active View AdExchange average time in seconds that specific + impressions are reported as being viewable. + + Corresponds to "Ad Exchange Active View average viewable + time (seconds)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + AD_EXCHANGE_ACTIVE_VIEW_ELIGIBLE_IMPRESSIONS (76): + Total number of impressions delivered by Ad Exchange that + were eligible to measure viewability. + + Corresponds to "Ad Exchange Active View eligible + impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_EXCHANGE_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS (75): + The number of impressions delivered by Ad Exchange that were + sampled, and measurable by active view. + + Corresponds to "Ad Exchange Active View measurable + impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_EXCHANGE_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS_RATE (78): + The percentage of impressions delivered by Ad Exchange that + were measurable by active view (out of all Ad Exchange + impressions sampled for active view). + + Corresponds to "Ad Exchange Active View % measurable + impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_EXCHANGE_ACTIVE_VIEW_NON_MEASURABLE_IMPRESSIONS (654): + Ad Exchange Active View non-measurable impressions + + Corresponds to "Ad Exchange Active View non-measurable + impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_EXCHANGE_ACTIVE_VIEW_NON_VIEWABLE_IMPRESSIONS (655): + Ad Exchange Active View non-viewable impressions + + Corresponds to "Ad Exchange Active View non-viewable + impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_EXCHANGE_ACTIVE_VIEW_NON_VIEWABLE_IMPRESSIONS_DISTRIBUTION (656): + Ad Exchange Active View non-viewable impressions + distribution + + Corresponds to "Ad Exchange Active View non-viewable + impression distribution" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_EXCHANGE_ACTIVE_VIEW_UNDETERMINED_IMPRESSIONS_DISTRIBUTION (657): + Ad Exchange Active View undetermined impressions + distribution + + Corresponds to "Ad Exchange Active View undetermined + impression distribution" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_EXCHANGE_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS (74): + The number of impressions delivered by Ad Exchange viewed on + the user's screen. + + Corresponds to "Ad Exchange Active View viewable + impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_EXCHANGE_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_DISTRIBUTION (658): + Ad Exchange Active View viewable impressions distribution + + Corresponds to "Ad Exchange Active View viewable impression + distribution" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_EXCHANGE_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_RATE (77): + The percentage of impressions delivered by Ad Exchange + viewed on the user's screen (out of Ad Exchange impressions + measurable by active view). + + Corresponds to "Ad Exchange Active View % viewable + impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_EXCHANGE_AVERAGE_ECPM (18): + The average effective cost-per-thousand-impressions earned + from the ads delivered by Ad Exchange through line item + dynamic allocation. + + Corresponds to "Ad Exchange average eCPM" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + AD_EXCHANGE_CLICKS (15): + Number of clicks delivered by the Ad Exchange. + + Corresponds to "Ad Exchange clicks" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_EXCHANGE_CPC (244): + The average effective cost-per-click earned from the ads + delivered by Ad Exchange through line item dynamic + allocation. + + Corresponds to "Ad Exchange CPC" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + AD_EXCHANGE_CTR (16): + The ratio of impressions served by the Ad Exchange that + resulted in users clicking on an ad. The clickthrough rate + (CTR) is updated nightly. Ad Exchange CTR is calculated as: + (Ad Exchange clicks / Ad Exchange impressions). + + Corresponds to "Ad Exchange CTR" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_EXCHANGE_DELIVERY_RATE (245): + Ratio of impressions delivered by Ad Exchange through line + item dynamic allocation to ad requests. + + Corresponds to "Ad Exchange delivery rate" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_EXCHANGE_IMPRESSIONS (14): + Total impressions delivered by the Ad Exchange. + + Corresponds to "Ad Exchange impressions" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_EXCHANGE_IMPRESSIONS_PER_AD_VIEWER (427): + The total number of impressions based on the number of ad + viewers. + + Corresponds to "Ad Exchange impressions per ad viewer" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + AD_EXCHANGE_IMPRESSIONS_PER_SESSION (428): + The total number of impressions based on the number of + sessions. + + Corresponds to "Ad Exchange impressions per session" in the + Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + AD_EXCHANGE_LIFT (246): + The increase in revenue gained for won impressions over the + applicable third party price (the minimum CPM or the best + price specified during dynamic allocation), + + Corresponds to "Ad Exchange lift earnings" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_EXCHANGE_MATCHED_REQUEST_CTR (247): + The ratio of matched ad requests served by the Ad Exchange + that resulted in users clicking on an ad. The clickthrough + rate (CTR) is updated nightly. Ad Exchange Matched Request + CTR is calculated as: (Ad Exchange clicks / Ad Exchange + Macthed Ad Requests). + + Corresponds to "Ad Exchange matched request CTR" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_EXCHANGE_MATCHED_REQUEST_ECPM (248): + The average effective cost per thousand matched ad requests + earned from the ads delivered by Ad Exchange through line + item dynamic allocation. + + Corresponds to "Ad Exchange matched request eCPM" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + AD_EXCHANGE_MATCH_RATE (249): + The number of responses served divided by the number of + queries eligible in ad exchange. + + Corresponds to "Ad Exchange match rate" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_EXCHANGE_OPPORTUNITIES_FROM_ERRORS (250): + Total opportunities from video VAST error within the + waterfall for backfill ads. + + Corresponds to "Ad Exchange opportunities from errors" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_EXCHANGE_OPPORTUNITIES_FROM_IMPRESSIONS (251): + Number of opportunities from impressions within the + waterfall for backfill ads. + + Corresponds to "Ad Exchange opportunities from impressions" + in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_EXCHANGE_PERCENT_CLICKS (20): + Ratio of clicks delivered by Ad Exchange through line item + dynamic allocation in relation to the total clicks + delivered. + + Corresponds to "Ad Exchange clicks (%)" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_EXCHANGE_PERCENT_IMPRESSIONS (19): + Ratio of impressions delivered by Ad Exchange through line + item dynamic allocation in relation to the total impressions + delivered. + + Corresponds to "Ad Exchange impressions (%)" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_EXCHANGE_PERCENT_REVENUE (21): + Ratio of revenue generated by Ad Exchange through line item + dynamic allocation in relation to the total revenue. + + Corresponds to "Ad Exchange revenue (%)" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_EXCHANGE_PERCENT_REVENUE_WITHOUT_CPD (31): + Ratio of revenue generated by Ad Exchange through line item + dynamic allocation in relation to the total revenue + (excluding CPD). + + Corresponds to "Ad Exchange revenue w/o CPD (%)" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_EXCHANGE_PLUS_YIELD_GROUP_ECPM (252): + The average effective cost-per-thousand-impressions earned + from the ads delivered by Ad Exchange through line item + dynamic allocation and yield group partners. + + Corresponds to "Ad Exchange plus yield group eCPM" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + AD_EXCHANGE_PLUS_YIELD_GROUP_IMPRESSIONS (253): + Total impressions delivered by the Ad Exchange and + third-party networks. + + Corresponds to "Ad Exchange plus yield group impressions" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_EXCHANGE_PLUS_YIELD_GROUP_REVENUE (254): + Revenue generated from the Ad Exchange and Yield Group, + calculated in your network's currency and time zone. + + Corresponds to "Ad Exchange plus yield group revenue" in the + Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + AD_EXCHANGE_RESPONSES_SERVED (42): + The total number of times that an Ad Exchange ad is + delivered. + + Corresponds to "Ad Exchange responses served" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_EXCHANGE_REVENUE (17): + Revenue generated from the Ad Exchange through line item + dynamic allocation, calculated in your network's currency + and time zone. + + Corresponds to "Ad Exchange revenue" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + AD_EXCHANGE_REVENUE_PAID_THROUGH_MCM_AUTOPAYMENT (212): + The Ad Exchange revenue accrued in the child network's own + account but paid to their parent network through + auto-payment. This metric is only relevant for a "Manage + Account" child network. + + Corresponds to "Ad Exchange revenue paid through MCM + auto-payment" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + AD_EXCHANGE_REVENUE_PER_AD_VIEWER (429): + The total amount of Ad Exchange revenue based on the number + of ad viewers. + + Corresponds to "Ad Exchange revenue per ad viewer" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + AD_EXCHANGE_TOTAL_REQUESTS (255): + The number of programmatic eligible queries in Ad Exchange. + + Corresponds to "Ad Exchange total requests" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_EXCHANGE_TOTAL_REQUEST_CTR (256): + The ratio of total ad requests served by the Ad Exchange + that resulted in users clicking on an ad. The clickthrough + rate (CTR) is updated nightly. Ad Exchange Total Request CTR + is calculated as: (Ad Exchange clicks / Ad Exchange Total Ad + Requests). + + Corresponds to "Ad Exchange total request CTR" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_EXCHANGE_TOTAL_REQUEST_ECPM (257): + The average effective cost per thousand ad requests earned + from the ads delivered by Ad Exchange through line item + dynamic allocation and yield group partners. + + Corresponds to "Ad Exchange total request eCPM" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + AD_EXPOSURE_SECONDS (241): + Length of time in seconds that an ad is visible on the + user's screen from Google Analytics. + + Corresponds to "Ad exposure (seconds)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + AD_REQUESTS (38): + The total number of times that an ad request is sent to the + ad server including dynamic allocation. + + Corresponds to "Total ad requests" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_SERVER_ACTIVE_VIEW_AVERAGE_VIEWABLE_TIME (67): + Active View ad server average time in seconds that specific + impressions are reported as being viewable. + + Corresponds to "Ad server Active View average viewable time + (seconds)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + AD_SERVER_ACTIVE_VIEW_ELIGIBLE_IMPRESSIONS (64): + Total number of impressions delivered by the ad server that + were eligible to measure viewability. + + Corresponds to "Ad server Active View eligible impressions" + in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_SERVER_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS (63): + The number of impressions delivered by the ad server that + were sampled, and measurable by active view. + + Corresponds to "Ad server Active View measurable + impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_SERVER_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS_RATE (66): + The percentage of impressions delivered by the ad server + that were measurable by active view (out of all the ad + server impressions sampled for active view). + + Corresponds to "Ad server Active View % measurable + impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_SERVER_ACTIVE_VIEW_NON_MEASURABLE_IMPRESSIONS (332): + The number of impressions delivered by Ad Server that were + not measured. For example, impressions where measurement was + attempted but failed. + + Corresponds to "Ad server Active View non-measurable + impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_SERVER_ACTIVE_VIEW_NON_VIEWABLE_IMPRESSIONS (331): + The number of impressions delivered by Ad Server that were + measured by active view, but deemed not viewable. + + Corresponds to "Ad server Active View non-viewable + impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_SERVER_ACTIVE_VIEW_NON_VIEWABLE_IMPRESSIONS_DISTRIBUTION (334): + The fraction of non-viewable impressions among eligible + impressions from Ad Server in Active View reporting." + + Corresponds to "Ad server Active View non-viewable + impression distribution" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_SERVER_ACTIVE_VIEW_UNDETERMINED_IMPRESSIONS_DISTRIBUTION (335): + The fraction of non-eligible impressions among eligible + impressions from Ad Server in Active View reporting." + + Corresponds to "Ad server Active View undetermined + impression distribution" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_SERVER_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS (62): + The number of impressions delivered by the ad server viewed + on the user's screen. + + Corresponds to "Ad server Active View viewable impressions" + in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_SERVER_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_DISTRIBUTION (333): + The fraction of viewable impressions among eligible + impressions from Ad Server in Active View reporting. + + Corresponds to "Ad server Active View viewable impression + distribution" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_SERVER_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_RATE (65): + The percentage of impressions delivered by the ad server + viewed on the user's screen (out of the ad server + impressions measurable by active view). + + Corresponds to "Ad server Active View % viewable + impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_SERVER_AVERAGE_ECPM (34): + Average effective cost-per-thousand-impressions earned from + the ads delivered by the Google Ad Manager server. + + Corresponds to "Ad server average eCPM" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + AD_SERVER_AVERAGE_ECPM_WITHOUT_CPD (10): + Average effective cost-per-thousand-impressions earned from + the ads delivered by the Google Ad Manager server, excluding + CPD value. + + Corresponds to "Ad server average eCPM w/o CPD" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + AD_SERVER_BEGIN_TO_RENDER_IMPRESSIONS (262): + Total raw impressions counted when creative begins to render + or the first frame of a video is shown. + + Corresponds to "Ad server begin to render impressions" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_SERVER_CLICKS (7): + Total clicks served by the Google Ad Manager server. It + usually takes about 30 minutes for new clicks to be recorded + and added to the total displayed in reporting. + + Corresponds to "Ad server clicks" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_SERVER_COMPLETED_VIEWS (431): + The number of completed views for ad server. + + Corresponds to "Ad server completed views" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_SERVER_COVIEWED_IMPRESSIONS (554): + Total coviewed impressions delivered by the Ad Server. + + Corresponds to "Ad server impressions (co-viewed)" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_SERVER_CPD_REVENUE (32): + CPD revenue earned, calculated in your network's currency, + for the ads delivered by the Google Ad Manager server. Sum + of all booked revenue. + + Corresponds to "Ad server CPD revenue" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + AD_SERVER_CTR (8): + Ratio of impressions served by the Google Ad Manager server + that resulted in users clicking on an ad. The clickthrough + rate (CTR) is updated nightly. The ad server CTR is + calculated as: (Ad server clicks / Ad server impressions). + + Corresponds to "Ad server CTR" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_SERVER_GROSS_REVENUE (483): + Gross revenue earned, calculated in your network's currency, + for the ads delivered by the Google Ad Manager server. This + includes pre-rev-share revenue for Programmatic traffic. + This metric is to help with the transition from gross to net + revenue reporting. + + Corresponds to "Ad server total revenue (gross)" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + AD_SERVER_GROSS_REVENUE_WITHOUT_CPD (484): + Gross revenue earned, calculated in your network's currency, + for the ads delivered by the Google Ad Manager server, + excluding CPD revenue. This includes pre-rev-share revenue + for Programmatic traffic. This metric is to help with the + transition from gross to net revenue reporting. + + Corresponds to "Ad server CPM and CPC revenue (gross)" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + AD_SERVER_IMPRESSIONS (6): + Total impressions delivered by the Ad Server. + + Corresponds to "Ad server impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_SERVER_IMPRESSIONS_WITH_COMPANION (222): + Total impressions delivered by the Ad Server with companion + impressions. + + Corresponds to "Ad server impressions with companion" in the + Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_SERVER_INACTIVE_BEGIN_TO_RENDER_IMPRESSIONS (338): + Impressions (via begin to render methodology) delivered by + the Google Ad Manager server considered inactive, as defined + by served to a device receiving ad or bid requests + continuously for a session of greater than 16 hours without + a "reset" event. + + Corresponds to "Ad server inactive begin to render + impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_SERVER_PERCENT_CLICKS (12): + Ratio of clicks delivered by the Google Ad Manager server in + relation to the total clicks delivered. + + Corresponds to "Ad server clicks (%)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_SERVER_PERCENT_IMPRESSIONS (11): + Ratio of impressions delivered by the Google Ad Manager + server in relation to the total impressions delivered. + + Corresponds to "Ad server impressions (%)" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_SERVER_PERCENT_REVENUE (35): + Ratio of revenue generated by the Google Ad Manager server + in relation to the total revenue. + + Corresponds to "Ad server revenue (%)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_SERVER_PERCENT_REVENUE_WITHOUT_CPD (13): + Ratio of revenue generated by the Google Ad Manager server + (excluding CPD) in relation to the total revenue. + + Corresponds to "Ad server revenue w/o CPD (%)" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + AD_SERVER_RESPONSES_SERVED (40): + The total number of times that an ad is served by the ad + server. + + Corresponds to "Ad server responses served" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_SERVER_REVENUE (33): + All CPM, CPC, and CPD revenue earned, calculated in your + network's currency, for the ads delivered by the Google Ad + Manager server. Sum of all booked revenue. + + Corresponds to "Ad server total revenue" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + AD_SERVER_REVENUE_PAID_THROUGH_MCM_AUTOPAYMENT (213): + The Google Ad Manager server revenue accrued in the child + network's own account but paid to their parent network + through auto-payment. This metric is only relevant for a + "Manage Account" child network. + + Corresponds to "Ad server revenue paid through MCM + auto-payment" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + AD_SERVER_REVENUE_WITHOUT_CPD (9): + Revenue (excluding CPD) earned, calculated in your network's + currency, for the ads delivered by the Google Ad Manager + server. Sum of all booked revenue. + + Corresponds to "Ad server CPM and CPC revenue" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + AD_SERVER_TARGETED_CLICKS (274): + The number of clicks delivered by the ad server by explicit + custom criteria targeting. + + Corresponds to "Ad server targeted clicks" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_SERVER_TARGETED_IMPRESSIONS (275): + The number of impressions delivered by the ad server by + explicit custom criteria targeting. + + Corresponds to "Ad server targeted impressions" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_SERVER_TRACKED_ADS (264): + The number of tracked ads delivered by the ad server. + + Corresponds to "Ad server tracked ads" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_SERVER_UNFILTERED_BEGIN_TO_RENDER_IMPRESSIONS (261): + Total raw impressions counted when creative begins to render + or the first frame of a video is shown, before invalid + traffic filtrations by Ad Server. + + Corresponds to "Ad server unfiltered begin to render + impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_SERVER_UNFILTERED_CLICKS (259): + Total clicks delivered by the Ad Server before spam + filtering. + + Corresponds to "Ad server unfiltered clicks" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_SERVER_UNFILTERED_DOWNLOADED_IMPRESSIONS (260): + Total downloaded impressions delivered by the Ad Server + before spam filtering. + + Corresponds to "Ad server unfiltered downloaded impressions" + in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_SERVER_UNFILTERED_IMPRESSIONS (260): + Deprecated. This metric has been renamed to + ``AD_SERVER_UNFILTERED_DOWNLOADED_IMPRESSIONS``. The server + will normalize any requests using this value to + ``AD_SERVER_UNFILTERED_DOWNLOADED_IMPRESSIONS``. This value + will be removed on or after October 1, 2025. + AD_SERVER_UNFILTERED_TRACKED_ADS (263): + The number of tracked ads delivered by the ad server before + invalid traffic filtrations. + + Corresponds to "Ad server unfiltered tracked ads" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + AD_UNIT_EXPOSURE_SECONDS (242): + Length of time in seconds that an ad unit is visible on the + user's screen from Google Analytics. + + Corresponds to "Ad unit exposure (seconds)" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + AD_VIEWERS (425): + The number of users who viewed an ads on your site or app in + the specified date range from Google Analytics. + + Corresponds to "Ad viewers" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + ATN_ADS_FAILED_TO_RENDER (430): + Number of ads that Ad Manager failed to render in the Ads + traffic navigator report. + + Corresponds to "Ads failed to render" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_ELIGIBLE_LINE_ITEMS (342): + Number of line items that matched an ad request in the Ads + traffic navigator report. + + Corresponds to "Eligible line items" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_ELIGIBLE_LINE_ITEMS_AD_REQUESTS (343): + Number of ad requests that contain eligible line items for + the auction in the Ads traffic navigator report. + + Corresponds to "Ad requests with eligible line items" in the + Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_HBT_ALLOWED_AD_REQUESTS (344): + Number of ad requests that have header bidding trafficking + demand in the Ads traffic navigator report. + + Corresponds to "Ad requests allowing header bidding + trafficking" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_HBT_BIDS_IN_AUCTION (345): + Number of header bidding trafficking bids that are able to + match an ad request and enter the auction in the Ads traffic + navigator report. + + Corresponds to "Competing header bidding trafficking bids" + in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_HBT_BIDS_IN_AUCTION_AD_REQUESTS (346): + Number of header bidding trafficking ad requests with bids + in auction in the Ads traffic navigator report. + + Corresponds to "Ad requests with competing header bidding + trafficking bids" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_HBT_CANDIDATE_BIDS (347): + Number of header bidding trafficking candidate bids that + match an ad request in the Ads traffic navigator report. + + Corresponds to "Header bidding trafficking bids" in the Ad + Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_HBT_INVALID_AD_REQUESTS (348): + Number of invalid header bidding trafficking ad requests in + the Ads traffic navigator report. + + Corresponds to "Invalid ad requests allowing header bidding + trafficking" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_HBT_NO_BIDS_AD_REQUESTS (472): + Number of header bidding trafficking ad requests with no + bids in the Ads traffic navigator report. + + Corresponds to "Header bidding trafficking ad requests with + no bids" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_HBT_REJECTED_BIDS (349): + Number of header bidding trafficking bids that didn't match + the ad request in the Ads traffic navigator report. + + Corresponds to "Rejected header bidding trafficking bids" in + the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_HBT_VALID_AD_REQUESTS (350): + Number of ad requests with the header bidding trafficking + demand that are valid in the Ads traffic navigator report. + + Corresponds to "Valid header bidding trafficking ad + requests" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_HBT_WITH_BIDS_AD_REQUESTS (473): + Number of header bidding trafficking ad requests with bids + in the Ads traffic navigator report. + + Corresponds to "Header bidding trafficking ad requests with + bids" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_INVALID_AD_REQUESTS (351): + Ad requests that are not valid in the Ads traffic navigator + report. + + Corresponds to "Invalid ad requests" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_LINE_ITEMS_CREATIVE_NOT_RETRIEVED (476): + Number of line items with no creative retrieved in the Ads + traffic navigator report. + + Corresponds to "Creative not retrieved" in the Ad Manager + UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_LINE_ITEMS_IN_AUCTION (352): + Number of line items that matched an ad request and entered + in auction in the Ads traffic navigator report. + + Corresponds to "Competing line items" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_LINE_ITEMS_NOT_COMPETING (515): + Number of line items that were ranked but did not compete in + auction in the Ads traffic navigator report. + + Corresponds to "Non-competing line items" in the Ad Manager + UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_LINE_ITEMS_NOT_SELECTED (353): + Number of line items that matched an ad request but were not + selected to compete in the auction in the Ads traffic + navigator report. + + Corresponds to "Not selected to compete" in the Ad Manager + UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_LINE_ITEM_IN_AUCTION_AD_REQUESTS (354): + Number of line item ad requests in auction in the Ads + traffic navigator report. + + Corresponds to "Ad requests with competing line items" in + the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_LINE_ITEM_TARGETED_AD_REQUESTS (355): + Number of line item targeted ad requests in the Ads traffic + navigator report. + + Corresponds to "Ad requests with targeted line items" in the + Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_MEDIATION_ALLOWED_AD_REQUESTS (356): + Number of ad requests with the mediation demand in the Ads + traffic navigator report. + + Corresponds to "Ad requests allowing mediation" in the Ad + Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_MEDIATION_INVALID_AD_REQUESTS (357): + Number of invalid mediation ad requests in the Ads traffic + navigator report. + + Corresponds to "Invalid ad requests allowing mediation" in + the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_MEDIATION_LOADED_ADS_FROM_CHAINS (358): + Number of times the Yield Partner's ad was loaded in the Ads + traffic navigator report. + + Corresponds to "Loaded ads from chains" in the Ad Manager + UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_MEDIATION_NO_PARTNER_AD_REQUESTS (474): + Number of ad requests with mediation demand having no + partners in the Ads traffic navigator report. + + Corresponds to "Mediation requests with no partners" in the + Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_MEDIATION_PARTNERS_IN_AUCTION (359): + Number of mediation yield partners in auction in the Ads + traffic navigator report. + + Corresponds to "Competing mediation partners" in the Ad + Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_MEDIATION_PARTNERS_IN_AUCTION_AD_REQUESTS (360): + Number of ad requests in auction that serve mediation chains + in the Ads traffic navigator report. + + Corresponds to "Ad requests with competing mediation + partners" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_MEDIATION_REJECTED_PARTNERS (361): + Number of mediation partners that didn't match an ad request + in the Ads traffic navigator report. + + Corresponds to "Rejected partners" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_MEDIATION_TARGETED_PARTNERS (362): + Number of mediation partners that have targeted an ad + request and are able to match it in the Ads traffic + navigator report. + + Corresponds to "Targeted mediation partners" in the Ad + Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_MEDIATION_TOTAL_YIELD_PARTNERS (442): + Number of partners on served mediation chains in the Ads + traffic navigator report. + + Corresponds to "Total yield partners" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_MEDIATION_UNLOADED_ADS_FROM_CHAINS (363): + Number of ads from mediation chains that Ad Manager won't + serve in the Ads traffic navigator report. + + Corresponds to "Unloaded ads from chains" in the Ad Manager + UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_MEDIATION_UNUSED_BIDS_OR_PARTNERS (364): + Number of times the Yield Partner's mediation chain ad was + not reached in the Ads traffic navigator report. + + Corresponds to "Unused bids or partners" in the Ad Manager + UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_MEDIATION_VALID_AD_REQUESTS (365): + Number of ad requests that have mediation demand in the Ads + traffic navigator report. + + Corresponds to "Valid mediation ad requests" in the Ad + Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_MEDIATION_WITH_PARTNERS_AD_REQUESTS (475): + Number of ad requests with mediation demand having partners + in the Ads traffic navigator report. + + Corresponds to "Ad requests with targeted mediation + partners" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_PROGRAMMATIC_AD_REQUESTS_WITH_BIDS (366): + Number of ad requests with programmatic demand that have + received a bid in the Ads traffic navigator report. + + Corresponds to "Ad requests with bids" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_PROGRAMMATIC_AD_REQUESTS_WITH_BID_REQUESTS_SENT (367): + Number of ad requests with programmatic demand that have + sent a bid to at least one buyer in the Ads traffic + navigator report. + + Corresponds to "Ad requests with bid requests sent" in the + Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_PROGRAMMATIC_ALLOWED_AD_REQUESTS (368): + Number of ad requests with programmatic demand in the Ads + traffic navigator report. + + Corresponds to "Ad requests allowing programmatic" in the Ad + Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_PROGRAMMATIC_BIDS_IN_AUCTION (369): + Number of ads with programmatic bids that entered the + auction in the Ads traffic navigator report. + + Corresponds to "Competing programmatic bids" in the Ad + Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_PROGRAMMATIC_BID_IN_AUCTION_AD_REQUESTS (370): + Number of ad requests that have received eligible + programmatic bids to compete in the auction in the Ads + traffic navigator report. + + Corresponds to "Ad requests with competing programmatic + bids" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_PROGRAMMATIC_BID_REQUESTS_SENT (371): + Number of programmatic callout bid requests sent to buyers + in the Ads traffic navigator report. + + Corresponds to "Bid requests sent" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_PROGRAMMATIC_BID_REQUESTS_WITH_RESPONSE (372): + Number of programmatic callout bid requests that resulted + with a response in the Ads traffic navigator report. + + Corresponds to "Bid requests with response" in the Ad + Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_PROGRAMMATIC_BID_REQUEST_CANDIDATES (373): + All buyers that Ad Manager could potentially send a + programmatic bid request to in the Ads traffic navigator + report. + + Corresponds to "Bid request candidates" in the Ad Manager + UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_PROGRAMMATIC_BID_REQUEST_ERRORS (374): + Number of programmatic callout bid requests with errors in + the Ads traffic navigator report. + + Corresponds to "Bid request errors" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_PROGRAMMATIC_INELIGIBLE_AD_REQUESTS (375): + Number of ad requests that are ineligible for programmatic + in the Ads traffic navigator report. + + Corresponds to "Invalid ad requests allowing programmatic" + in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_PROGRAMMATIC_REJECTED_BIDS (376): + Number of programmatic callout bids rejected in the Ads + traffic navigator report. + + Corresponds to "Rejected bids" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_PROGRAMMATIC_SKIPPED_BID_REQUESTS (377): + Number of programmatic callout bid requests Ad Manager won't + send to buyers in the Ads traffic navigator report. + + Corresponds to "Skipped bid requests" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_PROGRAMMATIC_TOTAL_BIDS (378): + Number of programmatic bids that Ad Manager received from + buyers in the Ads traffic navigator report. + + Corresponds to "Total programmatic bids" in the Ad Manager + UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_PROGRAMMATIC_VALID_AD_REQUESTS (379): + Number of ad requests that allow programmatic in the Ads + traffic navigator report. + + Corresponds to "Valid ad requests allowing programmatic" in + the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_REJECTED_LINE_ITEMS (380): + Number of line items targeted that didn't match an ad + request in the Ads traffic navigator report. + + Corresponds to "Rejected line items" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_SERVED_MEDIATION_CHAINS (381): + Number of mediation chains Ad Manager serves in the Ads + traffic navigator report. + + Corresponds to "Served mediation chains" in the Ad Manager + UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_SERVED_SINGLE_ADS (382): + Number of single ads served in the Ads traffic navigator + report. + + Corresponds to "Served single ads" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_TARGETED_LINE_ITEMS (383): + Number of line items with targeting that matches an ad + request in the Ads traffic navigator report. + + Corresponds to "Targeted line items" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_TOTAL_AD_REQUESTS (384): + Total number of ad requests which counts optimized pod + request as a single request in the Ads traffic navigator + report. + + Corresponds to "Total ad requests (ATN)" in the Ad Manager + UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_TOTAL_COMPETING_ADS_IN_AUCTION (385): + Number of competing ads in auction in the Ads traffic + navigator report. + + Corresponds to "Total competing ads" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_TOTAL_LOADED_ADS (387): + Total number of ads loaded in the Ads traffic navigator + report. + + Corresponds to "Total loaded ads" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_VALID_AD_REQUESTS (389): + Ad requests that are valid in the Ads traffic navigator + report. + + Corresponds to "Valid ad requests" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + ATN_YIELD_GROUP_MEDIATION_PASSBACKS (390): + Number of times the Yield Partner passed-back on a Mediation + chain ad in the Ads traffic navigator report. + + Corresponds to "Yield group mediation passbacks" in the Ad + Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + AVERAGE_ECPM (37): + eCPM averaged across the Google Ad Manager server, AdSense, + and Ad Exchange. + + Corresponds to "Total average eCPM" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + AVERAGE_ECPM_WITHOUT_CPD (5): + eCPM averaged across the Google Ad Manager server (excluding + CPD), AdSense, and Ad Exchange. + + Corresponds to "Total average eCPM w/o CPD" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + AVERAGE_ENGAGEMENT_SECONDS_PER_SESSION (224): + Average user engagement seconds per session in Google + Analytics. + + Corresponds to "Average engagement time per session + (seconds)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + AVERAGE_ENGAGEMENT_SECONDS_PER_USER (225): + Average user engagement seconds per user in Google + Analytics. + + Corresponds to "Average engagement time per user (seconds)" + in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + AVERAGE_IMPRESSIONS_PER_UNIQUE_VISITOR (418): + The average number of unique users reached per ad + impression. + + Corresponds to "Average impressions/unique visitor" in the + Ad Manager UI. + + Compatible with the following report types: ``REACH`` + + Data format: ``DOUBLE`` + AVERAGE_PURCHASE_REVENUE_PER_PAYING_USER (226): + Average total purchase revenue per user in Google Analytics. + + Corresponds to "ARPPU" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + AVERAGE_REVENUE_PER_USER (227): + Average revenue earned from each active user in Google + Analytics. + + Corresponds to "ARPU" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + AVERAGE_SESSION_SECONDS (228): + Average length of a session in Google Analytics. + + Corresponds to "Average session duration (seconds)" in the + Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + BIDS (443): + The number of bids. + + Corresponds to "Bids" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + BID_AVERAGE_CPM (444): + The average CPM of the bids submitted by bidders. + + Corresponds to "Average bid CPM" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + BOUNCE_RATE (433): + The ratio of (sessions - engaged sessions) / sessions. + + Corresponds to "Bounce rate" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + CLICKS (2): + The number of times a user clicked on an ad. + + Corresponds to "Total clicks" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + CODE_SERVED_COUNT (44): + The total number of times that the code for an ad is served + by the ad server including dynamic allocation. + + Corresponds to "Total code served count" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + CPC_REVENUE (440): + Total amount of CPC revenue. + + Corresponds to "CPC revenue" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``MONEY`` + CPM_REVENUE (441): + Total amount of CPM revenue. + + Corresponds to "CPM revenue" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``MONEY`` + CREATIVE_LOAD_TIME_0_500_PERCENT (324): + Percent of creatives whose load time is between [0, 500ms). + + Corresponds to "Creative load time 0 - 500ms (%)" in the Ad + Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + CREATIVE_LOAD_TIME_1000_2000_PERCENT (326): + Percent of creatives whose load time is between [1000, + 2000ms). + + Corresponds to "Creative load time 1s - 2s (%)" in the Ad + Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + CREATIVE_LOAD_TIME_2000_4000_PERCENT (327): + Percent of creatives whose load time is between [2000, + 4000ms). + + Corresponds to "Creative load time 2s - 4s (%)" in the Ad + Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + CREATIVE_LOAD_TIME_4000_8000_PERCENT (328): + Percent of creatives whose load time is between [4000, + 8000ms). + + Corresponds to "Creative load time 4s - 8s (%)" in the Ad + Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + CREATIVE_LOAD_TIME_500_1000_PERCENT (325): + Percent of creatives whose load time is between [500, + 1000ms). + + Corresponds to "Creative load time 500ms - 1s (%)" in the Ad + Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + CREATIVE_LOAD_TIME_GT_8000_PERCENT (329): + Percent of creatives load time is greater than 8000ms. + + Corresponds to "Creative load time >8s (%)" in the Ad + Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + CTR (3): + For standard ads, your ad clickthrough rate (CTR) is the + number of ad clicks divided by the number of individual ad + impressions expressed as a fraction. Ad CTR = Clicks / Ad + impressions. + + Corresponds to "Total CTR" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + DEALS_BIDS (542): + Number of bids received for a deal. + + Corresponds to "Deals bids" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + DEALS_BID_RATE (543): + Bid rate for a deal. + + Corresponds to "Deals bid rate" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + DEALS_BID_REQUESTS (544): + Number of bid requests sent for a deal. + + Corresponds to "Deals bid requests" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + DEALS_WINNING_BIDS (545): + Number of winning bids for a deal. + + Corresponds to "Deals winning bids" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + DEALS_WIN_RATE (546): + Bid win rate for a deal. + + Corresponds to "Deals win rate" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + DOM_LOAD_TO_FIRST_AD_REQUEST_0_500_PERCENT (521): + Percent of dom load time to 1st ad request in [0, 500ms) + range. + + Corresponds to "Page navigation to first ad request time 0 - + 500ms (%)" in the Ad Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + DOM_LOAD_TO_FIRST_AD_REQUEST_1000_2000_PERCENT (522): + Percent of dom load time to 1st ad request in [1000ms, + 2000ms) range. + + Corresponds to "Page navigation to first ad request time 1s + - 2s (%)" in the Ad Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + DOM_LOAD_TO_FIRST_AD_REQUEST_2000_4000_PERCENT (523): + Percent of dom load time to 1st ad request in [2000ms, + 4000ms) range. + + Corresponds to "Page navigation to first ad request time 2s + - 4s (%)" in the Ad Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + DOM_LOAD_TO_FIRST_AD_REQUEST_4000_8000_PERCENT (524): + Percent of dom load time to 1st ad request in [4000ms, + 8000ms) range. + + Corresponds to "Page navigation to first ad request time 4s + - 8s (%)" in the Ad Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + DOM_LOAD_TO_FIRST_AD_REQUEST_500_1000_PERCENT (525): + Percent of dom load time to 1st ad request in [500ms, + 1000ms) range. + + Corresponds to "Page navigation to first ad request time + 500ms - 1s (%)" in the Ad Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + DOM_LOAD_TO_FIRST_AD_REQUEST_GT_8000_PERCENT (520): + Percent of dom load time to 1st ad request in [8000ms, +inf) + range. + + Corresponds to "Page navigation to first ad request time >8s + (%)" in the Ad Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + DOM_LOAD_TO_TAG_LOAD_TIME_0_500_PERCENT (526): + Percent of dom load time to tag load time in [0, 500ms) + range. + + Corresponds to "Page navigation to tag loaded time 0 - 500ms + (%)" in the Ad Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + DOM_LOAD_TO_TAG_LOAD_TIME_1000_2000_PERCENT (527): + Percent of dom load time to tag load time in [1000ms, + 2000ms) range. + + Corresponds to "Page navigation to tag loaded time 1s - 2s + (%)" in the Ad Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + DOM_LOAD_TO_TAG_LOAD_TIME_2000_4000_PERCENT (528): + Percent of dom load time to tag load time in [2000ms, + 4000ms) range. + + Corresponds to "Page navigation to tag loaded time 2s - 4s + (%)" in the Ad Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + DOM_LOAD_TO_TAG_LOAD_TIME_4000_8000_PERCENT (529): + Percent of dom load time to tag load time in [4000ms, + 8000ms) range. + + Corresponds to "Page navigation to tag loaded time 4s - 8s + (%)" in the Ad Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + DOM_LOAD_TO_TAG_LOAD_TIME_500_1000_PERCENT (531): + Percent of dom load time to tag load time in [500ms, 1000ms) + range. + + Corresponds to "Page navigation to tag loaded time 500ms - + 1s (%)" in the Ad Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + DOM_LOAD_TO_TAG_LOAD_TIME_GT_8000_PERCENT (530): + Percent of dom load time to tag load time in [8000ms, +inf) + range. + + Corresponds to "Page navigation to tag loaded time >8s (%)" + in the Ad Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + DROPOFF_RATE (415): + Percentage of ad responses that didn't result in an + impression. + + Corresponds to "Drop-off rate" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + ENGAGED_SESSIONS (229): + Engaged session count from Google Analytics. + + Corresponds to "Engaged sessions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + ENGAGED_SESSIONS_PER_USER (230): + Engaged sessions per user from Google Analytics. + + Corresponds to "Engaged sessions per user" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + ENGAGEMENT_RATE (426): + The ratio of engaged sessions to sessions. + + Corresponds to "Engagement rate" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + EUROPEAN_REGULATIONS_CONSENT_RATE (270): + Percentage of European regulations messages where the user + consented to all of the purposes and vendors. + + Corresponds to "European regulations consent rate" in the Ad + Manager UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``PERCENT`` + EUROPEAN_REGULATIONS_CUSTOM_CONSENT_RATE (271): + Percentage of European regulations messages where users made + a consent choice after selecting "Manage options". + + Corresponds to "European regulations custom consent rate" in + the Ad Manager UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``PERCENT`` + EUROPEAN_REGULATIONS_MESSAGES_SHOWN (272): + Number of times a European regulations message was shown to + users. + + Corresponds to "European regulations messages shown" in the + Ad Manager UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``INTEGER`` + EUROPEAN_REGULATIONS_NO_CONSENT_RATE (273): + Percentage of European regulations messages where the user + rejected all purposes and vendors. + + Corresponds to "European regulations no consent rate" in the + Ad Manager UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``PERCENT`` + FILL_RATE (258): + The rate at which an ad request is filled by the ad server + including dynamic allocation. + + Corresponds to "Total fill rate" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + GOOGLE_ANALYTICS_CLICKS (231): + The number of clicks joined with Google Analytics data. + + Corresponds to "Google Analytics clicks" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + GOOGLE_ANALYTICS_CTR (232): + The click-through rate from Google Analytics data. + + Corresponds to "Google Analytics CTR" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + GOOGLE_ANALYTICS_ECPM (233): + The eCPM revenue data from Google Analytics. + + Corresponds to "Google Analytics eCPM" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + GOOGLE_ANALYTICS_IMPRESSIONS (234): + The number of impressions joined with Google Analytics data. + + Corresponds to "Google Analytics impressions" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + GOOGLE_ANALYTICS_REVENUE (235): + The amount of revenue joined with Google Analytics data. + + Corresponds to "Google Analytics revenue" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + GOOGLE_ANALYTICS_VIEWS (236): + Number of views of a web site or mobile screen from Google + Analytics. + + Corresponds to "Views" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + GOOGLE_ANALYTICS_VIEWS_PER_USER (237): + Number of views per user from Google Analytics. + + Corresponds to "Views per user" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + GOOGLE_SOLD_AUCTION_COVIEWED_IMPRESSIONS (129): + The number of coviewed impressions sold by Google in partner + sales. + + Corresponds to "Google-sold auction impressions (co-viewed)" + in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + GOOGLE_SOLD_AUCTION_IMPRESSIONS (128): + The number of auction impressions sold by Google in partner + sales. + + Corresponds to "Google-sold auction impressions" in the Ad + Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + GOOGLE_SOLD_COVIEWED_IMPRESSIONS (131): + The number of coviewed impressions sold by Google in partner + sales. + + Corresponds to "Google-sold impressions (co-viewed)" in the + Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + GOOGLE_SOLD_IMPRESSIONS (130): + The number of impressions sold by Google in partner sales. + + Corresponds to "Google-sold impressions" in the Ad Manager + UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + GOOGLE_SOLD_RESERVATION_COVIEWED_IMPRESSIONS (127): + The number of coviewed impressions sold by Google in partner + sales. + + Corresponds to "Google-sold reservation impressions + (co-viewed)" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + GOOGLE_SOLD_RESERVATION_IMPRESSIONS (126): + The number of reservation impressions sold by Google in + partner sales. + + Corresponds to "Google-sold reservation impressions" in the + Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + IMPRESSIONS (1): + Total impressions from the Google Ad Manager server, + AdSense, Ad Exchange, and yield group partners. + + Corresponds to "Total impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + INACTIVE_BEGIN_TO_RENDER_IMPRESSIONS (407): + The number of impressions (via begin to render methodology) + considered inactive, as defined by served to a device + receiving ad or bid requests continuously for a session of + greater than 16 hours without a "reset" event. Only applied + to CTV ads. + + Corresponds to "Inactive begin to render impressions" in the + Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + INVENTORY_SHARES (547): + The total number of inventory shares + + Corresponds to "Inventory shares" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + INVENTORY_SHARE_PARTNER_UNFILLED_OPPORTUNITIES (548): + The total number of partner unfilled opportunities from an + inventory share + + Corresponds to "Inventory share partner unfilled + opportunities" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + INVOICED_IMPRESSIONS (404): + The number of invoiced impressions. + + Corresponds to "Invoiced impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + INVOICED_UNFILLED_IMPRESSIONS (405): + The number of invoiced unfilled impressions. + + Corresponds to "Invoiced unfilled impressions" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + MEDIATION_CHAINS_FILLED (584): + The number of mediation chains that were filled. + + Corresponds to "Mediation chains filled" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + MUTED_IMPRESSIONS (412): + The number of impressions where the user chose to mute the + ad. + + Corresponds to "Total muted impressions" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + MUTE_ELIGIBLE_IMPRESSIONS (409): + The number of impressions that had the "Mute This Ad" + overlay applied. + + Corresponds to "Total mute eligible impressions" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + OPPORTUNITIES (463): + The total number of opportunities from impressions and + errors. + + Corresponds to "Total opportunities" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + OVERDELIVERED_IMPRESSIONS (432): + The number of impressions that were overdelivered. + + Corresponds to "Total overdelivered impressions" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + PARTNER_SALES_FILLED_POD_REQUESTS (135): + The number of filled pod requests (filled by partner or + Google) in partner sales. + + Corresponds to "Filled pod requests" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + PARTNER_SALES_FILL_RATE (136): + The percent of filled requests to total ad requests in + partner sales. + + Corresponds to "Fill rate" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``PERCENT`` + PARTNER_SALES_PARTNER_MATCH_RATE (137): + The percent of partner filled requests to total ad requests + in partner sales. + + Corresponds to "Partner match rate" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``PERCENT`` + PARTNER_SALES_QUERIES (132): + The number of queries eligible for partner sales. + + Corresponds to "Total partner sales ad requests" in the Ad + Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + PARTNER_SALES_UNFILLED_IMPRESSIONS (133): + The number of partner unfilled impressions in partner sales. + If a pod request is not filled by partner but filled by + Google, this metric will still count 1. + + Corresponds to "Partner unfilled impressions" in the Ad + Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + PARTNER_SALES_UNMATCHED_QUERIES (134): + The number of partner unmatched queries in partner sales. If + an ad request is not filled by partner but filled by Google, + this metric will still count 1. + + Corresponds to "Partner unmatched ad requests" in the Ad + Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + PARTNER_SOLD_CODE_SERVED (125): + The number of code served sold by partner in partner sales. + + Corresponds to "Partner-sold code served count" in the Ad + Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + PARTNER_SOLD_COVIEWED_IMPRESSIONS (124): + The number of coviewed impressions sold by partner in + partner sales. + + Corresponds to "Partner-sold impressions (co-viewed)" in the + Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + PARTNER_SOLD_IMPRESSIONS (123): + The number of impressions sold by partner in partner sales. + + Corresponds to "Partner-sold impressions" in the Ad Manager + UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + PROGRAMMATIC_ELIGIBLE_AD_REQUESTS (177): + The total number of ad requests eligible for programmatic + inventory, including Programmatic Guaranteed, Preferred + Deals, backfill, and open auction. + + Corresponds to "Programmatic eligible ad requests" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + PROGRAMMATIC_MATCH_RATE (178): + The number of programmatic responses served divided by the + number of programmatic eligible ad requests. Includes Ad + Exchange, Open Bidding, and Preferred Deals. + + Corresponds to "Programmatic match rate" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + PROGRAMMATIC_RESPONSES_SERVED (176): + Total number of ad responses served from programmatic demand + sources. Includes Ad Exchange, Open Bidding, and Preferred + Deals. + + Differs from AD_EXCHANGE_RESPONSES_SERVED, which doesn't + include Open Bidding ad requests. + + Corresponds to "Programmatic responses served" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + REACH_IMPRESSIONS (416): + Number of impressions for reach reports. + + Corresponds to "Total reach impressions" in the Ad Manager + UI. + + Compatible with the following report types: ``REACH`` + + Data format: ``INTEGER`` + RESPONSES_SERVED (39): + The total number of times that an ad is served by the ad + server including dynamic allocation. + + Corresponds to "Total responses served" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + RETENTION (238): + Retention of users in Google Analytics + + Corresponds to "Retention" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + REVENUE (36): + Total amount of CPM, CPC, and CPD revenue based on the + number of units served by the Google Ad Manager server, + AdSense, Ad Exchange, and third-party Mediation networks. + + Corresponds to "Total revenue" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + REVENUE_PAID_THROUGH_MCM_AUTOPAYMENT (214): + The total revenue accrued in the child network's own account + but paid to their parent network through auto-payment. This + metric is only relevant for a "Manage Account" child + network. + + Corresponds to "Total revenue paid through MCM auto-payment" + in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + REVENUE_WITHOUT_CPD (4): + Total amount of revenue (excluding CPD) based on the number + of units served by the Google Ad Manager server, AdSense, Ad + Exchange, and third-party Mediation networks. + + Corresponds to "Total CPM and CPC revenue" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + REWARDS_GRANTED (413): + The number of rewards granted to users from watching ads. + + Corresponds to "Total rewards granted" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + RICH_MEDIA_AVERAGE_DISPLAY_TIME (587): + The average amount of time (in seconds) that each rich media + ad is displayed to users. + + Corresponds to "Average display time" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + RICH_MEDIA_AVERAGE_INTERACTION_TIME (588): + The average amount of time (in seconds) that a user + interacts with a rich media ad. + + Corresponds to "Average interaction time" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + RICH_MEDIA_BACKUP_IMAGES (589): + The total number of times a backup image is served in place + of a rich media ad. + + Corresponds to "Backup image impressions" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + RICH_MEDIA_CUSTOM_EVENT_COUNT (599): + The number of times a user interacts with a specific part of + a rich media ad. + + Corresponds to "Custom event - count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + RICH_MEDIA_CUSTOM_EVENT_TIME (600): + The amount of time (in seconds) that a user interacts with a + specific part of a rich media ad. + + Corresponds to "Custom event - time" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + RICH_MEDIA_DISPLAY_TIME (590): + The amount of time (in seconds) that each rich media ad is + displayed to users. + + Corresponds to "Total display time" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + RICH_MEDIA_EXPANDING_TIME (591): + The average amount of time (in seconds) that an expanding ad + is viewed in an expanded state. + + Corresponds to "Average expanding time" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + RICH_MEDIA_EXPANSIONS (592): + The number of times an expanding ad was expanded. + + Corresponds to "Total expansions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + RICH_MEDIA_FULL_SCREEN_IMPRESSIONS (593): + The number of times a user opens a rich media ad in full + screen mode. + + Corresponds to "Full-screen impressions" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + RICH_MEDIA_INTERACTION_COUNT (594): + The number of times that a user interacts with a rich media + ad. + + Corresponds to "Total interactions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + RICH_MEDIA_INTERACTION_RATE (595): + The ratio of rich media ad interactions to the number of + times the ad was displayed. + + Corresponds to "Interaction rate" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + RICH_MEDIA_INTERACTION_TIME (596): + The total amount of time (in seconds) that a user interacts + with a rich media ad. + + Corresponds to "Interaction time" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + RICH_MEDIA_INTERACTIVE_IMPRESSIONS (597): + The number of impressions where a user interacted with a + rich media ad. + + Corresponds to "Interactive impressions" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + RICH_MEDIA_MANUAL_CLOSES (598): + The number of times that a user manually closes a rich media + ad. + + Corresponds to "Manual closes" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + RICH_MEDIA_VIDEO_COMPLETES (503): + The number of times a rich media video was fully played. + + Corresponds to "Rich media video completes" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + RICH_MEDIA_VIDEO_INTERACTIONS (505): + The number of times a user clicked on the graphical controls + of a video player. + + Corresponds to "Rich media total video interactions" in the + Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + RICH_MEDIA_VIDEO_INTERACTION_RATE (504): + The ratio of video interactions to video plays. Represented + as a percentage. + + Corresponds to "Rich media video interaction rate" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + RICH_MEDIA_VIDEO_MIDPOINTS (506): + The number of times a rich media video was played up to + midpoint. + + Corresponds to "Rich media video midpoints" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + RICH_MEDIA_VIDEO_MUTES (507): + The number of times a rich media video was muted. + + Corresponds to "Rich media video mutes" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + RICH_MEDIA_VIDEO_PAUSES (508): + The number of times a rich media video was paused. + + Corresponds to "Rich media video pauses" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + RICH_MEDIA_VIDEO_PLAYS (509): + The number of times a rich media video was played. + + Corresponds to "Rich media video plays" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + RICH_MEDIA_VIDEO_REPLAYS (510): + The number of times a rich media video was restarted. + + Corresponds to "Rich media video replays" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + RICH_MEDIA_VIDEO_STOPS (511): + The number of times a rich media video was stopped. + + Corresponds to "Rich media video stops" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + RICH_MEDIA_VIDEO_UNMUTES (512): + The number of times a rich media video was unmuted. + + Corresponds to "Rich media video unmutes" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + RICH_MEDIA_VIDEO_VIEW_RATE (513): + The percentage of a video watched by a user. + + Corresponds to "Rich media video view rate" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + RICH_MEDIA_VIDEO_VIEW_TIME (514): + The average amount of time(seconds) that a rich media video + was viewed per view. + + Corresponds to "Rich media video average view time" in the + Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + SELL_THROUGH_AVAILABLE_IMPRESSIONS (477): + The number of forecasted impressions not reserved by any + line item. + + Corresponds to "Available impressions" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + SELL_THROUGH_FORECASTED_IMPRESSIONS (478): + The total number of forecasted impressions. + + Corresponds to "Forecasted impressions" in the Ad Manager + UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + SELL_THROUGH_RESERVED_IMPRESSIONS (479): + The number of forecasted impressions reserved by line items. + + Corresponds to "Reserved impressions" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + SELL_THROUGH_SELL_THROUGH_RATE (480): + The fraction of forecasted impressions reserved by line + items. + + Corresponds to "Sell-through rate" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``PERCENT`` + SERVER_SIDE_UNWRAPPING_AVERAGE_LATENCY_MS (434): + The average latency in milliseconds across all server-side + unwrapping callout requests. There is no special handling + for error or timeout responses. This reflects the entire + chain of a parent callout request, which may result in + multiple child callouts. This metric is not sliced by child + callout dimensions. + + Corresponds to "Server-side unwrapping average latency + (milliseconds)" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + SERVER_SIDE_UNWRAPPING_CALLOUTS (435): + The total number of server-side unwrapping callout requests. + + Corresponds to "Server-side unwrapping callouts" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + SERVER_SIDE_UNWRAPPING_EMPTY_RESPONSES (436): + The total number of server-side unwrapping callouts that + returned an empty response. Timeouts are not considered + empty responses. + + Corresponds to "Server-side unwrapping empty responses" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + SERVER_SIDE_UNWRAPPING_ERROR_RESPONSES (437): + The total number of server-side unwrapping callouts that + returned an error response. Timeouts and empty responses are + not considered errors. + + Corresponds to "Server-side unwrapping error responses" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + SERVER_SIDE_UNWRAPPING_SUCCESSFUL_RESPONSES (438): + The total number of successfully unwrapped, non-empty + server-side wrapping callouts. Successful unwrapping does + not indicate that the resulting creative was served. + + Corresponds to "Server-side unwrapping successful responses" + in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + SERVER_SIDE_UNWRAPPING_TIMEOUTS (439): + The total number of server-side unwrapping callouts that + timed out before returning a response. + + Corresponds to "Server-side unwrapping timeouts" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + SESSIONS (239): + Count of sessions from Google Analytics. + + Corresponds to "Sessions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + TAG_LOAD_TO_FIRST_AD_REQUEST_0_500_PERCENT (455): + Percent of tag load time to 1st ad request in [0, 500ms) + range. + + Corresponds to "Tag loaded to first ad request time 0 - + 500ms (%)" in the Ad Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + TAG_LOAD_TO_FIRST_AD_REQUEST_1000_2000_PERCENT (457): + Percent of tag load time to 1st ad request in [1000ms, + 2000ms) range. + + Corresponds to "Tag loaded to first ad request time 1s - 2s + (%)" in the Ad Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + TAG_LOAD_TO_FIRST_AD_REQUEST_2000_4000_PERCENT (458): + Percent of tag load time to 1st ad request in [2000ms, + 4000ms) range. + + Corresponds to "Tag loaded to first ad request time 2s - 4s + (%)" in the Ad Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + TAG_LOAD_TO_FIRST_AD_REQUEST_4000_8000_PERCENT (459): + Percent of tag load time to 1st ad request in [4000ms, + 8000ms) range. + + Corresponds to "Tag loaded to first ad request time 4s - 8s + (%)" in the Ad Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + TAG_LOAD_TO_FIRST_AD_REQUEST_500_1000_PERCENT (456): + Percent of tag load time to 1st ad request in [500ms, + 1000ms) range. + + Corresponds to "Tag loaded to first ad request time 500ms - + 1s (%)" in the Ad Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + TAG_LOAD_TO_FIRST_AD_REQUEST_GT_8000_PERCENT (460): + Percent of tag load time to 1st ad request in [8000ms, +inf) + range. + + Corresponds to "Tag loaded to first ad request time >8s (%)" + in the Ad Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + TARGETED_CLICKS (276): + The total number of clicks delivered including line + item-level dynamic allocation by explicit custom criteria + targeting. + + Corresponds to "Total targeted clicks" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + TARGETED_IMPRESSIONS (277): + The total number of impressions delivered including line + item-level dynamic allocation by explicit custom criteria + targeting. + + Corresponds to "Total targeted impressions" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + UNFILLED_IMPRESSIONS (45): + The total number of missed impressions due to the ad + servers' inability to find ads to serve including dynamic + allocation. + + Corresponds to "Unfilled impressions" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + UNIQUE_VISITORS (417): + The total number of unique users who viewed the ad. + + Corresponds to "Total unique visitors" in the Ad Manager UI. + + Compatible with the following report types: ``REACH`` + + Data format: ``INTEGER`` + UNLOADED_IMPRESSIONS_DUE_TO_CPU (408): + The number of impressions impacted by Chrome Ads + Intervention due to CPU usage. + + Corresponds to "Total unloaded impressions due to CPU" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + UNLOADED_IMPRESSIONS_DUE_TO_NETWORK (406): + The number of impressions impacted by Chrome Ads + Intervention due to network usage. + + Corresponds to "Total unloaded impressions due to Network" + in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + UNMATCHED_AD_REQUESTS (43): + The total number of times that an ad is not returned by the + ad server. + + Corresponds to "Total unmatched ad requests" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + UNVIEWED_REASON_OTHER_PERCENT (550): + The percentage of unviewed impressions due to other reasons. + + Corresponds to "Other non-viewable impression reasons (%)" + in the Ad Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + UNVIEWED_REASON_SLOT_NEVER_ENTERED_VIEWPORT_PERCENT (553): + The percentage of unviewed impressions due to slot never + entered viewport. + + Corresponds to "Slot never entered viewport (%)" in the Ad + Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + UNVIEWED_REASON_USER_SCROLLED_BEFORE_AD_FILLED_PERCENT (551): + The percentage of unviewed impressions due to scrolled past + before ad filled. + + Corresponds to "User scrolled before ad filled (%)" in the + Ad Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + UNVIEWED_REASON_USER_SCROLLED_BEFORE_AD_LOADED_PERCENT (552): + The percentage of unviewed impressions due to scrolled past + before ad loaded. + + Corresponds to "User scrolled/navigated before ad loaded + (%)" in the Ad Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + UNVIEWED_REASON_USER_SCROLLED_BEFORE_ONE_SECOND_PERCENT (549): + The percentage of unviewed impressions due to insufficient + time on screen. + + Corresponds to "User scrolled/navigated before 1 second (%)" + in the Ad Manager UI. + + Compatible with the following report types: ``AD_SPEED`` + + Data format: ``PERCENT`` + USER_ENGAGEMENT_DURATION_IN_SECONDS (240): + Time of users interacting with web site or mobile app from + Google Analytics in seconds. + + Corresponds to "User engagement duration (seconds)" in the + Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + USER_MESSAGES_AD_BLOCKING_EXTENSION_RATE (486): + Fraction of page views where users had ad blocker extensions + installed. Includes only Desktop page views. + + Corresponds to "Ad blocking extension rate" in the Ad + Manager UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``PERCENT`` + USER_MESSAGES_AD_BLOCKING_RECOVERY_ALLOWLISTED_COUNT (487): + Number of ad-blocking messages shown in the selected date + range that resulted in users adding the site to their + allowlist to view ads + + Corresponds to "Ad blocking recovery message conversions" in + the Ad Manager UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``INTEGER`` + USER_MESSAGES_AD_BLOCKING_RECOVERY_MESSAGES_SHOWN (488): + Number of times an ad blocking recovery message was shown to + users. + + Corresponds to "Ad blocking recovery messages shown" in the + Ad Manager UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``INTEGER`` + USER_MESSAGES_ALLOW_ADS_PAGEVIEWS (489): + The number of page views generated by users with an ad + blocking extension installed who were shown the ad blocking + recovery message and later allowed ads. + + Corresponds to "Allow-ads page views" in the Ad Manager UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``INTEGER`` + USER_MESSAGES_CCPA_MESSAGES_SHOWN (490): + Number of times a US state regulations message was shown to + users. + + Corresponds to "US states messages shown" in the Ad Manager + UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``INTEGER`` + USER_MESSAGES_IDFA_ATT_ALERTS_SHOWN (491): + Number of iOS ATT alerts that were triggered by an IDFA + message (IDFA messages can be IDFA explainers or GDPR + messages). + + Corresponds to "IDFA ATT alerts shown" in the Ad Manager UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``INTEGER`` + USER_MESSAGES_IDFA_ATT_CONSENT (492): + Number of iOS ATT alerts triggered by the IDFA message where + the user chose to allow tracking. + + Corresponds to "IDFA ATT consent" in the Ad Manager UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``INTEGER`` + USER_MESSAGES_IDFA_ATT_CONSENT_RATE (493): + Percentage of iOS ATT alerts triggered by the IDFA message + where the outcome was to allow tracking. + + Corresponds to "IDFA ATT consent rate" in the Ad Manager UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``PERCENT`` + USER_MESSAGES_IDFA_ATT_DECLINE_CONSENT (494): + Number of iOS ATT alerts triggered by the IDFA message where + the user chose to deny tracking. + + Corresponds to "IDFA ATT decline consent" in the Ad Manager + UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``INTEGER`` + USER_MESSAGES_IDFA_ATT_DECLINE_RATE (495): + Percentage of iOS ATT alerts triggered by the IDFA message + where the user chose to deny tracking. + + Corresponds to "IDFA ATT decline rate" in the Ad Manager UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``PERCENT`` + USER_MESSAGES_IDFA_EXPLAINERS_SHOWN (496): + Number of times an IDFA explainer message was shown to + users. + + Corresponds to "IDFA explainers shown" in the Ad Manager UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``INTEGER`` + USER_MESSAGES_IDFA_IAB_MESSAGES_SHOWN (497): + Number of times a European regulations message was shown + immediately before the iOS ATT alert. + + Corresponds to "IDFA IAB messages shown" in the Ad Manager + UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``INTEGER`` + USER_MESSAGES_IDFA_NO_DECISION (498): + Number of IDFA explainer messages where the user didn't + choose anything. + + Corresponds to "IDFA no decision" in the Ad Manager UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``INTEGER`` + USER_MESSAGES_OFFERWALL_MESSAGES_SHOWN (121): + Number of times an Offerwall message was shown to users. + + Corresponds to "Offerwall messages shown" in the Ad Manager + UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``INTEGER`` + USER_MESSAGES_OFFERWALL_SUCCESSFUL_ENGAGEMENTS (122): + The number of messages where the user gained an entitlement. + + Corresponds to "Monetized Offerwall engagements" in the Ad + Manager UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``INTEGER`` + USER_MESSAGES_POST_OFFERWALL_PAGEVIEWS (499): + The number of pages viewed by users after gaining an + entitlement. Only counts pages included for Offerwall. + + Corresponds to "Post-offerwall page views" in the Ad Manager + UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``INTEGER`` + USER_MESSAGES_TOTAL_ESTIMATED_REVENUE (500): + Revenue earned through Offerwall, including Rewarded ad + revenue and third-party integrations. + + Corresponds to "Estimated Offerwall revenue" in the Ad + Manager UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``MONEY`` + USER_MESSAGES_UPTC_MESSAGES_SHOWN (501): + Number of times an ads personalization controls message was + shown to users. + + Corresponds to "Ads personalization messages shown" in the + Ad Manager UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``INTEGER`` + USER_MESSAGES_UPTC_PERSONALIZATION_OPT_OUT_RATIO (502): + Percentage of ads personalization controls messages where + users chose the opt-out option. + + Corresponds to "Personalization opt-out ratio" in the Ad + Manager UI. + + Compatible with the following report types: + ``PRIVACY_AND_MESSAGING`` + + Data format: ``PERCENT`` + VIDEO_ERROR_100_COUNT (180): + The number of errors of type 100 in reporting. + + Corresponds to "VAST error 100 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_101_COUNT (181): + The number of errors of type 101 in reporting. + + Corresponds to "VAST error 101 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_102_COUNT (182): + The number of errors of type 102 in reporting. + + Corresponds to "VAST error 102 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_200_COUNT (183): + The number of errors of type 200 in reporting. + + Corresponds to "VAST error 200 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_201_COUNT (184): + The number of errors of type 201 in reporting. + + Corresponds to "VAST error 201 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_202_COUNT (185): + The number of errors of type 202 in reporting. + + Corresponds to "VAST error 202 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_203_COUNT (186): + The number of errors of type 203 in reporting. + + Corresponds to "VAST error 203 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_300_COUNT (187): + The number of errors of type 300 in reporting. + + Corresponds to "VAST error 300 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_301_COUNT (188): + The number of errors of type 301 in reporting. + + Corresponds to "VAST error 301 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_302_COUNT (189): + The number of errors of type 302 in reporting. + + Corresponds to "VAST error 302 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_303_COUNT (190): + The number of errors of type 303 in reporting. + + Corresponds to "VAST error 303 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_400_COUNT (191): + The number of errors of type 400 in reporting. + + Corresponds to "VAST error 400 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_401_COUNT (192): + The number of errors of type 401 in reporting. + + Corresponds to "VAST error 401 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_402_COUNT (193): + The number of errors of type 402 in reporting. + + Corresponds to "VAST error 402 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_403_COUNT (194): + The number of errors of type 403 in reporting. + + Corresponds to "VAST error 403 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_405_COUNT (195): + The number of errors of type 405 in reporting. + + Corresponds to "VAST error 405 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_406_COUNT (196): + The number of errors of type 406 in reporting. + + Corresponds to "VAST error 406 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_407_COUNT (197): + The number of errors of type 407 in reporting. + + Corresponds to "VAST error 407 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_408_COUNT (198): + The number of errors of type 408 in reporting. + + Corresponds to "VAST error 408 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_409_COUNT (199): + The number of errors of type 409 in reporting. + + Corresponds to "VAST error 409 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_410_COUNT (200): + The number of errors of type 410 in reporting. + + Corresponds to "VAST error 410 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_500_COUNT (201): + The number of errors of type 500 in reporting. + + Corresponds to "VAST error 500 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_501_COUNT (202): + The number of errors of type 501 in reporting. + + Corresponds to "VAST error 501 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_502_COUNT (203): + The number of errors of type 502 in reporting. + + Corresponds to "VAST error 502 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_503_COUNT (204): + The number of errors of type 503 in reporting. + + Corresponds to "VAST error 503 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_600_COUNT (205): + The number of errors of type 600 in reporting. + + Corresponds to "VAST error 600 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_601_COUNT (206): + The number of errors of type 601 in reporting. + + Corresponds to "VAST error 601 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_602_COUNT (207): + The number of errors of type 602 in reporting. + + Corresponds to "VAST error 602 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_603_COUNT (208): + The number of errors of type 603 in reporting. + + Corresponds to "VAST error 603 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_604_COUNT (209): + The number of errors of type 604 in reporting. + + Corresponds to "VAST error 604 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_900_COUNT (210): + The number of errors of type 900 in reporting. + + Corresponds to "VAST error 900 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_ERROR_901_COUNT (211): + The number of errors of type 901 in reporting. + + Corresponds to "VAST error 901 count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_INTERACTION_AVERAGE_INTERACTION_RATE (92): + The number of user interactions with a video, on average, + such as pause, full screen, mute, etc. + + Corresponds to "Average interaction rate" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + VIDEO_INTERACTION_COLLAPSES (93): + The number of times a user collapses a video, either to its + original size or to a different size. + + Corresponds to "Collapses" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_INTERACTION_EXPANDS (95): + The number of times a user expands a video. + + Corresponds to "Expands" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_INTERACTION_FULL_SCREENS (96): + The number of times ad clip played in full screen mode. + + Corresponds to "Full screens" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_INTERACTION_MUTES (97): + The number of times video player was in mute state during + play of ad clip. + + Corresponds to "Mutes" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_INTERACTION_PAUSES (98): + The number of times user paused ad clip. + + Corresponds to "Pauses" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_INTERACTION_RESUMES (99): + The number of times the user unpaused the video. + + Corresponds to "Resumes" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_INTERACTION_REWINDS (100): + The number of times a user rewinds the video. + + Corresponds to "Rewinds" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_INTERACTION_UNMUTES (101): + The number of times a user unmutes the video. + + Corresponds to "Unmutes" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_INTERACTION_VIDEO_SKIPS (102): + The number of times a skippable video is skipped. + + Corresponds to "Skips" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_MONETIZABLE_CONTENT_VIEWS (601): + The number of views for monetizable video content. + + Corresponds to "Monetizable content views" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_CREATIVE_SERVES (139): + The number of total creative serves in video realtime + reporting. + + Corresponds to "Total creative serves" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_100_COUNT (143): + The number of errors of type 100 in video realtime + reporting. + + Corresponds to "VAST error 100 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_101_COUNT (144): + The number of errors of type 101 in video realtime + reporting. + + Corresponds to "VAST error 101 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_102_COUNT (145): + The number of errors of type 102 in video realtime + reporting. + + Corresponds to "VAST error 102 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_200_COUNT (146): + The number of errors of type 200 in video realtime + reporting. + + Corresponds to "VAST error 200 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_201_COUNT (147): + The number of errors of type 201 in video realtime + reporting. + + Corresponds to "VAST error 201 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_202_COUNT (148): + The number of errors of type 202 in video realtime + reporting. + + Corresponds to "VAST error 202 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_203_COUNT (149): + The number of errors of type 203 in video realtime + reporting. + + Corresponds to "VAST error 203 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_300_COUNT (150): + The number of errors of type 300 in video realtime + reporting. + + Corresponds to "VAST error 300 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_301_COUNT (151): + The number of errors of type 301 in video realtime + reporting. + + Corresponds to "VAST error 301 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_302_COUNT (152): + The number of errors of type 302 in video realtime + reporting. + + Corresponds to "VAST error 302 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_303_COUNT (153): + The number of errors of type 303 in video realtime + reporting. + + Corresponds to "VAST error 303 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_400_COUNT (154): + The number of errors of type 400 in video realtime + reporting. + + Corresponds to "VAST error 400 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_401_COUNT (155): + The number of errors of type 401 in video realtime + reporting. + + Corresponds to "VAST error 401 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_402_COUNT (156): + The number of errors of type 402 in video realtime + reporting. + + Corresponds to "VAST error 402 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_403_COUNT (157): + The number of errors of type 403 in video realtime + reporting. + + Corresponds to "VAST error 403 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_405_COUNT (158): + The number of errors of type 405 in video realtime + reporting. + + Corresponds to "VAST error 405 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_406_COUNT (159): + The number of errors of type 406 in video realtime + reporting. + + Corresponds to "VAST error 406 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_407_COUNT (160): + The number of errors of type 407 in video realtime + reporting. + + Corresponds to "VAST error 407 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_408_COUNT (161): + The number of errors of type 408 in video realtime + reporting. + + Corresponds to "VAST error 408 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_409_COUNT (162): + The number of errors of type 409 in video realtime + reporting. + + Corresponds to "VAST error 409 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_410_COUNT (163): + The number of errors of type 410 in video realtime + reporting. + + Corresponds to "VAST error 410 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_500_COUNT (164): + The number of errors of type 500 in video realtime + reporting. + + Corresponds to "VAST error 500 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_501_COUNT (165): + The number of errors of type 501 in video realtime + reporting. + + Corresponds to "VAST error 501 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_502_COUNT (166): + The number of errors of type 502 in video realtime + reporting. + + Corresponds to "VAST error 502 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_503_COUNT (167): + The number of errors of type 503 in video realtime + reporting. + + Corresponds to "VAST error 503 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_600_COUNT (168): + The number of errors of type 600 in video realtime + reporting. + + Corresponds to "VAST error 600 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_601_COUNT (169): + The number of errors of type 601 in video realtime + reporting. + + Corresponds to "VAST error 601 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_602_COUNT (170): + The number of errors of type 602 in video realtime + reporting. + + Corresponds to "VAST error 602 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_603_COUNT (171): + The number of errors of type 603 in video realtime + reporting. + + Corresponds to "VAST error 603 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_604_COUNT (172): + The number of errors of type 604 in video realtime + reporting. + + Corresponds to "VAST error 604 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_900_COUNT (173): + The number of errors of type 900 in video realtime + reporting. + + Corresponds to "VAST error 900 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_ERROR_901_COUNT (174): + The number of errors of type 901 in video realtime + reporting. + + Corresponds to "VAST error 901 count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_IMPRESSIONS (138): + The number of total impressions in video realtime reporting. + + Corresponds to "Total impressions" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_MATCHED_QUERIES (140): + The number of matched queries in video realtime reporting. + + Corresponds to "Total responses served" in the Ad Manager + UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_TOTAL_ERROR_COUNT (175): + The number of all errors in video realtime reporting. + + Corresponds to "Total error count" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_TOTAL_QUERIES (142): + The number of total queries in video realtime reporting. + + Corresponds to "Total ad requests" in the Ad Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_REAL_TIME_UNMATCHED_QUERIES (141): + The number of unmatched queries in video realtime reporting. + + Corresponds to "Total unmatched ad requests" in the Ad + Manager UI. + + Compatible with the following report types: + + Data format: ``INTEGER`` + VIDEO_VIEWERSHIP_AUTO_PLAYS (103): + Number of times that the publisher specified a video ad + played automatically. + + Corresponds to "Auto-plays" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_VIEWERSHIP_AVERAGE_VIEW_RATE (104): + Average percentage of the video watched by users. + + Corresponds to "Average view rate" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + VIDEO_VIEWERSHIP_AVERAGE_VIEW_TIME (105): + Average time(seconds) users watched the video. + + Corresponds to "Average view time" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + VIDEO_VIEWERSHIP_CLICK_TO_PLAYS (106): + Number of times that the publisher specified a video ad was + clicked to play. + + Corresponds to "Click-to-plays" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_VIEWERSHIP_COMPLETES (107): + The number of times the video played to completion. + + Corresponds to "Completes" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_VIEWERSHIP_COMPLETION_RATE (108): + Percentage of times the video played to the end. + + Corresponds to "Completion rate" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + VIDEO_VIEWERSHIP_ENGAGED_VIEWS (109): + The number of engaged views: ad is viewed to completion or + for 30s, whichever comes first. + + Corresponds to "Engaged views" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_VIEWERSHIP_FIRST_QUARTILES (110): + The number of times the video played to 25% of its length. + + Corresponds to "First quartiles" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_VIEWERSHIP_MIDPOINTS (111): + The number of times the video reached its midpoint during + play. + + Corresponds to "Midpoints" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_VIEWERSHIP_SKIP_BUTTONS_SHOWN (112): + The number of times a skip button is shown in video. + + Corresponds to "Skip buttons shown" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_VIEWERSHIP_STARTS (113): + The number of impressions where the video was played. + + Corresponds to "Starts" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_VIEWERSHIP_THIRD_QUARTILES (114): + The number of times the video played to 75% of its length. + + Corresponds to "Third quartiles" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_VIEWERSHIP_TOTAL_ERROR_COUNT (115): + The number of times an error occurred, such as a VAST + redirect error, a video playback error, or an invalid + response error. + + Corresponds to "Total error count" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + VIDEO_VIEWERSHIP_TOTAL_ERROR_RATE (94): + The percentage of video error count. + + Corresponds to "Total error rate" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + VIDEO_VIEWERSHIP_VIDEO_LENGTH (116): + Duration of the video creative. + + Corresponds to "Video length" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + VIDEO_VIEWERSHIP_VIEW_THROUGH_RATE (117): + View-through rate represented as a percentage. + + Corresponds to "Video view through rate" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``PERCENT`` + YIELD_GROUP_AUCTIONS_WON (80): + Number of winning bids received from Open Bidding buyers, + even when the winning bid is placed at the end of a + mediation for mobile apps chain. + + Corresponds to "Yield group auctions won" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + YIELD_GROUP_BIDS (81): + Number of bids received from Open Bidding buyers, regardless + of whether the returned bid competes in an auction. + + Corresponds to "Yield group bids" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + YIELD_GROUP_BIDS_IN_AUCTION (82): + Number of bids received from Open Bidding buyers that + competed in the auction. + + Corresponds to "Yield group bids in auction" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + YIELD_GROUP_CALLOUTS (83): + Number of times a yield partner is asked to return bid to + fill a yield group request. + + Corresponds to "Yield group callouts" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + YIELD_GROUP_ESTIMATED_CPM (88): + The estimated net rate for yield groups or individual yield + group partners. + + Corresponds to "Yield group estimated CPM" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + YIELD_GROUP_ESTIMATED_REVENUE (87): + Total net revenue earned by a yield group, based upon the + yield group estimated CPM and yield group impressions + recorded. + + Corresponds to "Yield group estimated revenue" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + YIELD_GROUP_IMPRESSIONS (85): + Number of matched yield group requests where a yield partner + delivered their ad to publisher inventory. + + Corresponds to "Yield group impressions" in the Ad Manager + UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + YIELD_GROUP_MEDIATION_FILL_RATE (89): + Yield group Mediation fill rate indicating how often a + network fills an ad request. + + Corresponds to "Yield group mediation fill rate" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + YIELD_GROUP_MEDIATION_MATCHED_QUERIES (86): + Total requests where a Mediation chain was served. + + Corresponds to "Yield group mediation matched queries" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + YIELD_GROUP_MEDIATION_PASSBACKS (118): + The number of mediation chain passback across all channels. + + Corresponds to "Yield group mediation passbacks" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + YIELD_GROUP_MEDIATION_THIRD_PARTY_ECPM (90): + Revenue per thousand impressions based on data collected by + Ad Manager from third-party ad network reports. + + Corresponds to "Yield group mediation third party ECPM" in + the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``DOUBLE`` + YIELD_GROUP_REVENUE_PAID_THROUGH_MCM_AUTOPAYMENT (215): + The yield group revenue accrued in the child network's own + account but paid to their parent network through + auto-payment. This metric is only relevant for a "Manage + Account" child network. + + Corresponds to "Yield group revenue paid through MCM + auto-payment" in the Ad Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``MONEY`` + YIELD_GROUP_SUCCESSFUL_RESPONSES (84): + Number of times a yield group buyer successfully returned a + bid in response to a yield group callout. + + Corresponds to "Yield group successful responses" in the Ad + Manager UI. + + Compatible with the following report types: ``HISTORICAL`` + + Data format: ``INTEGER`` + """ + _pb_options = {"allow_alias": True} + METRIC_UNSPECIFIED = 0 + ACTIVE_USERS = 223 + ACTIVE_VIEW_AUDIBLE_AT_START_PERCENT = 445 + ACTIVE_VIEW_AUDIBLE_IMPRESSIONS = 659 + ACTIVE_VIEW_AUDIBLE_THROUGH_COMPLETION_PERCENT = 446 + ACTIVE_VIEW_AUDIBLE_THROUGH_FIRST_QUARTILE_PERCENT = 447 + ACTIVE_VIEW_AUDIBLE_THROUGH_MIDPOINT_PERCENT = 448 + ACTIVE_VIEW_AUDIBLE_THROUGH_THIRD_QUARTILE_PERCENT = 449 + ACTIVE_VIEW_AUDIO_ENABLED_IMPRESSIONS = 660 + ACTIVE_VIEW_AUDIO_MEASURABLE_IMPRESSIONS = 661 + ACTIVE_VIEW_AVERAGE_VIEWABLE_TIME = 61 + ACTIVE_VIEW_ELIGIBLE_IMPRESSIONS = 58 + ACTIVE_VIEW_EVER_AUDIBLE_BACKGROUNDED_PERCENT = 450 + ACTIVE_VIEW_EVER_AUDIBLE_PERCENT = 451 + ACTIVE_VIEW_EVER_BACKGROUNDED_PERCENT = 452 + ACTIVE_VIEW_EVER_MUTED_PERCENT = 453 + ACTIVE_VIEW_IMPRESSIONS_AUDIBLE_AND_VISIBLIE_AT_COMPLETION = 411 + ACTIVE_VIEW_MEASURABLE_IMPRESSIONS = 57 + ACTIVE_VIEW_MEASURABLE_IMPRESSIONS_RATE = 60 + ACTIVE_VIEW_NON_MEASURABLE_IMPRESSIONS = 662 + ACTIVE_VIEW_NON_VIEWABLE_IMPRESSIONS = 663 + ACTIVE_VIEW_NON_VIEWABLE_IMPRESSIONS_DISTRIBUTION = 664 + ACTIVE_VIEW_PERCENT_AUDIBLE_IMPRESSIONS = 665 + ACTIVE_VIEW_PLUS_MEASURABLE_COUNT = 454 + ACTIVE_VIEW_REVENUE = 414 + ACTIVE_VIEW_UNDETERMINED_IMPRESSIONS_DISTRIBUTION = 666 + ACTIVE_VIEW_VIEWABLE_IMPRESSIONS = 56 + ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_DISTRIBUTION = 667 + ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_RATE = 59 + ADSENSE_ACTIVE_VIEW_AVERAGE_VIEWABLE_TIME = 73 + ADSENSE_ACTIVE_VIEW_ELIGIBLE_IMPRESSIONS = 70 + ADSENSE_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS = 69 + ADSENSE_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS_RATE = 72 + ADSENSE_ACTIVE_VIEW_NON_MEASURABLE_IMPRESSIONS = 642 + ADSENSE_ACTIVE_VIEW_NON_VIEWABLE_IMPRESSIONS = 643 + ADSENSE_ACTIVE_VIEW_NON_VIEWABLE_IMPRESSIONS_DISTRIBUTION = 644 + ADSENSE_ACTIVE_VIEW_UNDETERMINED_IMPRESSIONS_DISTRIBUTION = 645 + ADSENSE_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS = 68 + ADSENSE_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_DISTRIBUTION = 646 + ADSENSE_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_RATE = 71 + ADSENSE_AVERAGE_ECPM = 26 + ADSENSE_CLICKS = 23 + ADSENSE_CTR = 24 + ADSENSE_IMPRESSIONS = 22 + ADSENSE_PERCENT_CLICKS = 28 + ADSENSE_PERCENT_IMPRESSIONS = 27 + ADSENSE_PERCENT_REVENUE = 29 + ADSENSE_PERCENT_REVENUE_WITHOUT_CPD = 30 + ADSENSE_RESPONSES_SERVED = 41 + ADSENSE_REVENUE = 25 + AD_EXCHANGE_ACTIVE_VIEW_AVERAGE_VIEWABLE_TIME = 79 + AD_EXCHANGE_ACTIVE_VIEW_ELIGIBLE_IMPRESSIONS = 76 + AD_EXCHANGE_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS = 75 + AD_EXCHANGE_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS_RATE = 78 + AD_EXCHANGE_ACTIVE_VIEW_NON_MEASURABLE_IMPRESSIONS = 654 + AD_EXCHANGE_ACTIVE_VIEW_NON_VIEWABLE_IMPRESSIONS = 655 + AD_EXCHANGE_ACTIVE_VIEW_NON_VIEWABLE_IMPRESSIONS_DISTRIBUTION = 656 + AD_EXCHANGE_ACTIVE_VIEW_UNDETERMINED_IMPRESSIONS_DISTRIBUTION = 657 + AD_EXCHANGE_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS = 74 + AD_EXCHANGE_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_DISTRIBUTION = 658 + AD_EXCHANGE_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_RATE = 77 + AD_EXCHANGE_AVERAGE_ECPM = 18 + AD_EXCHANGE_CLICKS = 15 + AD_EXCHANGE_CPC = 244 + AD_EXCHANGE_CTR = 16 + AD_EXCHANGE_DELIVERY_RATE = 245 + AD_EXCHANGE_IMPRESSIONS = 14 + AD_EXCHANGE_IMPRESSIONS_PER_AD_VIEWER = 427 + AD_EXCHANGE_IMPRESSIONS_PER_SESSION = 428 + AD_EXCHANGE_LIFT = 246 + AD_EXCHANGE_MATCHED_REQUEST_CTR = 247 + AD_EXCHANGE_MATCHED_REQUEST_ECPM = 248 + AD_EXCHANGE_MATCH_RATE = 249 + AD_EXCHANGE_OPPORTUNITIES_FROM_ERRORS = 250 + AD_EXCHANGE_OPPORTUNITIES_FROM_IMPRESSIONS = 251 + AD_EXCHANGE_PERCENT_CLICKS = 20 + AD_EXCHANGE_PERCENT_IMPRESSIONS = 19 + AD_EXCHANGE_PERCENT_REVENUE = 21 + AD_EXCHANGE_PERCENT_REVENUE_WITHOUT_CPD = 31 + AD_EXCHANGE_PLUS_YIELD_GROUP_ECPM = 252 + AD_EXCHANGE_PLUS_YIELD_GROUP_IMPRESSIONS = 253 + AD_EXCHANGE_PLUS_YIELD_GROUP_REVENUE = 254 + AD_EXCHANGE_RESPONSES_SERVED = 42 + AD_EXCHANGE_REVENUE = 17 + AD_EXCHANGE_REVENUE_PAID_THROUGH_MCM_AUTOPAYMENT = 212 + AD_EXCHANGE_REVENUE_PER_AD_VIEWER = 429 + AD_EXCHANGE_TOTAL_REQUESTS = 255 + AD_EXCHANGE_TOTAL_REQUEST_CTR = 256 + AD_EXCHANGE_TOTAL_REQUEST_ECPM = 257 + AD_EXPOSURE_SECONDS = 241 + AD_REQUESTS = 38 + AD_SERVER_ACTIVE_VIEW_AVERAGE_VIEWABLE_TIME = 67 + AD_SERVER_ACTIVE_VIEW_ELIGIBLE_IMPRESSIONS = 64 + AD_SERVER_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS = 63 + AD_SERVER_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS_RATE = 66 + AD_SERVER_ACTIVE_VIEW_NON_MEASURABLE_IMPRESSIONS = 332 + AD_SERVER_ACTIVE_VIEW_NON_VIEWABLE_IMPRESSIONS = 331 + AD_SERVER_ACTIVE_VIEW_NON_VIEWABLE_IMPRESSIONS_DISTRIBUTION = 334 + AD_SERVER_ACTIVE_VIEW_UNDETERMINED_IMPRESSIONS_DISTRIBUTION = 335 + AD_SERVER_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS = 62 + AD_SERVER_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_DISTRIBUTION = 333 + AD_SERVER_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_RATE = 65 + AD_SERVER_AVERAGE_ECPM = 34 + AD_SERVER_AVERAGE_ECPM_WITHOUT_CPD = 10 + AD_SERVER_BEGIN_TO_RENDER_IMPRESSIONS = 262 + AD_SERVER_CLICKS = 7 + AD_SERVER_COMPLETED_VIEWS = 431 + AD_SERVER_COVIEWED_IMPRESSIONS = 554 + AD_SERVER_CPD_REVENUE = 32 + AD_SERVER_CTR = 8 + AD_SERVER_GROSS_REVENUE = 483 + AD_SERVER_GROSS_REVENUE_WITHOUT_CPD = 484 + AD_SERVER_IMPRESSIONS = 6 + AD_SERVER_IMPRESSIONS_WITH_COMPANION = 222 + AD_SERVER_INACTIVE_BEGIN_TO_RENDER_IMPRESSIONS = 338 + AD_SERVER_PERCENT_CLICKS = 12 + AD_SERVER_PERCENT_IMPRESSIONS = 11 + AD_SERVER_PERCENT_REVENUE = 35 + AD_SERVER_PERCENT_REVENUE_WITHOUT_CPD = 13 + AD_SERVER_RESPONSES_SERVED = 40 + AD_SERVER_REVENUE = 33 + AD_SERVER_REVENUE_PAID_THROUGH_MCM_AUTOPAYMENT = 213 + AD_SERVER_REVENUE_WITHOUT_CPD = 9 + AD_SERVER_TARGETED_CLICKS = 274 + AD_SERVER_TARGETED_IMPRESSIONS = 275 + AD_SERVER_TRACKED_ADS = 264 + AD_SERVER_UNFILTERED_BEGIN_TO_RENDER_IMPRESSIONS = 261 + AD_SERVER_UNFILTERED_CLICKS = 259 + AD_SERVER_UNFILTERED_DOWNLOADED_IMPRESSIONS = 260 + AD_SERVER_UNFILTERED_IMPRESSIONS = 260 + AD_SERVER_UNFILTERED_TRACKED_ADS = 263 + AD_UNIT_EXPOSURE_SECONDS = 242 + AD_VIEWERS = 425 + ATN_ADS_FAILED_TO_RENDER = 430 + ATN_ELIGIBLE_LINE_ITEMS = 342 + ATN_ELIGIBLE_LINE_ITEMS_AD_REQUESTS = 343 + ATN_HBT_ALLOWED_AD_REQUESTS = 344 + ATN_HBT_BIDS_IN_AUCTION = 345 + ATN_HBT_BIDS_IN_AUCTION_AD_REQUESTS = 346 + ATN_HBT_CANDIDATE_BIDS = 347 + ATN_HBT_INVALID_AD_REQUESTS = 348 + ATN_HBT_NO_BIDS_AD_REQUESTS = 472 + ATN_HBT_REJECTED_BIDS = 349 + ATN_HBT_VALID_AD_REQUESTS = 350 + ATN_HBT_WITH_BIDS_AD_REQUESTS = 473 + ATN_INVALID_AD_REQUESTS = 351 + ATN_LINE_ITEMS_CREATIVE_NOT_RETRIEVED = 476 + ATN_LINE_ITEMS_IN_AUCTION = 352 + ATN_LINE_ITEMS_NOT_COMPETING = 515 + ATN_LINE_ITEMS_NOT_SELECTED = 353 + ATN_LINE_ITEM_IN_AUCTION_AD_REQUESTS = 354 + ATN_LINE_ITEM_TARGETED_AD_REQUESTS = 355 + ATN_MEDIATION_ALLOWED_AD_REQUESTS = 356 + ATN_MEDIATION_INVALID_AD_REQUESTS = 357 + ATN_MEDIATION_LOADED_ADS_FROM_CHAINS = 358 + ATN_MEDIATION_NO_PARTNER_AD_REQUESTS = 474 + ATN_MEDIATION_PARTNERS_IN_AUCTION = 359 + ATN_MEDIATION_PARTNERS_IN_AUCTION_AD_REQUESTS = 360 + ATN_MEDIATION_REJECTED_PARTNERS = 361 + ATN_MEDIATION_TARGETED_PARTNERS = 362 + ATN_MEDIATION_TOTAL_YIELD_PARTNERS = 442 + ATN_MEDIATION_UNLOADED_ADS_FROM_CHAINS = 363 + ATN_MEDIATION_UNUSED_BIDS_OR_PARTNERS = 364 + ATN_MEDIATION_VALID_AD_REQUESTS = 365 + ATN_MEDIATION_WITH_PARTNERS_AD_REQUESTS = 475 + ATN_PROGRAMMATIC_AD_REQUESTS_WITH_BIDS = 366 + ATN_PROGRAMMATIC_AD_REQUESTS_WITH_BID_REQUESTS_SENT = 367 + ATN_PROGRAMMATIC_ALLOWED_AD_REQUESTS = 368 + ATN_PROGRAMMATIC_BIDS_IN_AUCTION = 369 + ATN_PROGRAMMATIC_BID_IN_AUCTION_AD_REQUESTS = 370 + ATN_PROGRAMMATIC_BID_REQUESTS_SENT = 371 + ATN_PROGRAMMATIC_BID_REQUESTS_WITH_RESPONSE = 372 + ATN_PROGRAMMATIC_BID_REQUEST_CANDIDATES = 373 + ATN_PROGRAMMATIC_BID_REQUEST_ERRORS = 374 + ATN_PROGRAMMATIC_INELIGIBLE_AD_REQUESTS = 375 + ATN_PROGRAMMATIC_REJECTED_BIDS = 376 + ATN_PROGRAMMATIC_SKIPPED_BID_REQUESTS = 377 + ATN_PROGRAMMATIC_TOTAL_BIDS = 378 + ATN_PROGRAMMATIC_VALID_AD_REQUESTS = 379 + ATN_REJECTED_LINE_ITEMS = 380 + ATN_SERVED_MEDIATION_CHAINS = 381 + ATN_SERVED_SINGLE_ADS = 382 + ATN_TARGETED_LINE_ITEMS = 383 + ATN_TOTAL_AD_REQUESTS = 384 + ATN_TOTAL_COMPETING_ADS_IN_AUCTION = 385 + ATN_TOTAL_LOADED_ADS = 387 + ATN_VALID_AD_REQUESTS = 389 + ATN_YIELD_GROUP_MEDIATION_PASSBACKS = 390 + AVERAGE_ECPM = 37 + AVERAGE_ECPM_WITHOUT_CPD = 5 + AVERAGE_ENGAGEMENT_SECONDS_PER_SESSION = 224 + AVERAGE_ENGAGEMENT_SECONDS_PER_USER = 225 + AVERAGE_IMPRESSIONS_PER_UNIQUE_VISITOR = 418 + AVERAGE_PURCHASE_REVENUE_PER_PAYING_USER = 226 + AVERAGE_REVENUE_PER_USER = 227 + AVERAGE_SESSION_SECONDS = 228 + BIDS = 443 + BID_AVERAGE_CPM = 444 + BOUNCE_RATE = 433 + CLICKS = 2 + CODE_SERVED_COUNT = 44 + CPC_REVENUE = 440 + CPM_REVENUE = 441 + CREATIVE_LOAD_TIME_0_500_PERCENT = 324 + CREATIVE_LOAD_TIME_1000_2000_PERCENT = 326 + CREATIVE_LOAD_TIME_2000_4000_PERCENT = 327 + CREATIVE_LOAD_TIME_4000_8000_PERCENT = 328 + CREATIVE_LOAD_TIME_500_1000_PERCENT = 325 + CREATIVE_LOAD_TIME_GT_8000_PERCENT = 329 + CTR = 3 + DEALS_BIDS = 542 + DEALS_BID_RATE = 543 + DEALS_BID_REQUESTS = 544 + DEALS_WINNING_BIDS = 545 + DEALS_WIN_RATE = 546 + DOM_LOAD_TO_FIRST_AD_REQUEST_0_500_PERCENT = 521 + DOM_LOAD_TO_FIRST_AD_REQUEST_1000_2000_PERCENT = 522 + DOM_LOAD_TO_FIRST_AD_REQUEST_2000_4000_PERCENT = 523 + DOM_LOAD_TO_FIRST_AD_REQUEST_4000_8000_PERCENT = 524 + DOM_LOAD_TO_FIRST_AD_REQUEST_500_1000_PERCENT = 525 + DOM_LOAD_TO_FIRST_AD_REQUEST_GT_8000_PERCENT = 520 + DOM_LOAD_TO_TAG_LOAD_TIME_0_500_PERCENT = 526 + DOM_LOAD_TO_TAG_LOAD_TIME_1000_2000_PERCENT = 527 + DOM_LOAD_TO_TAG_LOAD_TIME_2000_4000_PERCENT = 528 + DOM_LOAD_TO_TAG_LOAD_TIME_4000_8000_PERCENT = 529 + DOM_LOAD_TO_TAG_LOAD_TIME_500_1000_PERCENT = 531 + DOM_LOAD_TO_TAG_LOAD_TIME_GT_8000_PERCENT = 530 + DROPOFF_RATE = 415 + ENGAGED_SESSIONS = 229 + ENGAGED_SESSIONS_PER_USER = 230 + ENGAGEMENT_RATE = 426 + EUROPEAN_REGULATIONS_CONSENT_RATE = 270 + EUROPEAN_REGULATIONS_CUSTOM_CONSENT_RATE = 271 + EUROPEAN_REGULATIONS_MESSAGES_SHOWN = 272 + EUROPEAN_REGULATIONS_NO_CONSENT_RATE = 273 + FILL_RATE = 258 + GOOGLE_ANALYTICS_CLICKS = 231 + GOOGLE_ANALYTICS_CTR = 232 + GOOGLE_ANALYTICS_ECPM = 233 + GOOGLE_ANALYTICS_IMPRESSIONS = 234 + GOOGLE_ANALYTICS_REVENUE = 235 + GOOGLE_ANALYTICS_VIEWS = 236 + GOOGLE_ANALYTICS_VIEWS_PER_USER = 237 + GOOGLE_SOLD_AUCTION_COVIEWED_IMPRESSIONS = 129 + GOOGLE_SOLD_AUCTION_IMPRESSIONS = 128 + GOOGLE_SOLD_COVIEWED_IMPRESSIONS = 131 + GOOGLE_SOLD_IMPRESSIONS = 130 + GOOGLE_SOLD_RESERVATION_COVIEWED_IMPRESSIONS = 127 + GOOGLE_SOLD_RESERVATION_IMPRESSIONS = 126 + IMPRESSIONS = 1 + INACTIVE_BEGIN_TO_RENDER_IMPRESSIONS = 407 + INVENTORY_SHARES = 547 + INVENTORY_SHARE_PARTNER_UNFILLED_OPPORTUNITIES = 548 + INVOICED_IMPRESSIONS = 404 + INVOICED_UNFILLED_IMPRESSIONS = 405 + MEDIATION_CHAINS_FILLED = 584 + MUTED_IMPRESSIONS = 412 + MUTE_ELIGIBLE_IMPRESSIONS = 409 + OPPORTUNITIES = 463 + OVERDELIVERED_IMPRESSIONS = 432 + PARTNER_SALES_FILLED_POD_REQUESTS = 135 + PARTNER_SALES_FILL_RATE = 136 + PARTNER_SALES_PARTNER_MATCH_RATE = 137 + PARTNER_SALES_QUERIES = 132 + PARTNER_SALES_UNFILLED_IMPRESSIONS = 133 + PARTNER_SALES_UNMATCHED_QUERIES = 134 + PARTNER_SOLD_CODE_SERVED = 125 + PARTNER_SOLD_COVIEWED_IMPRESSIONS = 124 + PARTNER_SOLD_IMPRESSIONS = 123 + PROGRAMMATIC_ELIGIBLE_AD_REQUESTS = 177 + PROGRAMMATIC_MATCH_RATE = 178 + PROGRAMMATIC_RESPONSES_SERVED = 176 + REACH_IMPRESSIONS = 416 + RESPONSES_SERVED = 39 + RETENTION = 238 + REVENUE = 36 + REVENUE_PAID_THROUGH_MCM_AUTOPAYMENT = 214 + REVENUE_WITHOUT_CPD = 4 + REWARDS_GRANTED = 413 + RICH_MEDIA_AVERAGE_DISPLAY_TIME = 587 + RICH_MEDIA_AVERAGE_INTERACTION_TIME = 588 + RICH_MEDIA_BACKUP_IMAGES = 589 + RICH_MEDIA_CUSTOM_EVENT_COUNT = 599 + RICH_MEDIA_CUSTOM_EVENT_TIME = 600 + RICH_MEDIA_DISPLAY_TIME = 590 + RICH_MEDIA_EXPANDING_TIME = 591 + RICH_MEDIA_EXPANSIONS = 592 + RICH_MEDIA_FULL_SCREEN_IMPRESSIONS = 593 + RICH_MEDIA_INTERACTION_COUNT = 594 + RICH_MEDIA_INTERACTION_RATE = 595 + RICH_MEDIA_INTERACTION_TIME = 596 + RICH_MEDIA_INTERACTIVE_IMPRESSIONS = 597 + RICH_MEDIA_MANUAL_CLOSES = 598 + RICH_MEDIA_VIDEO_COMPLETES = 503 + RICH_MEDIA_VIDEO_INTERACTIONS = 505 + RICH_MEDIA_VIDEO_INTERACTION_RATE = 504 + RICH_MEDIA_VIDEO_MIDPOINTS = 506 + RICH_MEDIA_VIDEO_MUTES = 507 + RICH_MEDIA_VIDEO_PAUSES = 508 + RICH_MEDIA_VIDEO_PLAYS = 509 + RICH_MEDIA_VIDEO_REPLAYS = 510 + RICH_MEDIA_VIDEO_STOPS = 511 + RICH_MEDIA_VIDEO_UNMUTES = 512 + RICH_MEDIA_VIDEO_VIEW_RATE = 513 + RICH_MEDIA_VIDEO_VIEW_TIME = 514 + SELL_THROUGH_AVAILABLE_IMPRESSIONS = 477 + SELL_THROUGH_FORECASTED_IMPRESSIONS = 478 + SELL_THROUGH_RESERVED_IMPRESSIONS = 479 + SELL_THROUGH_SELL_THROUGH_RATE = 480 + SERVER_SIDE_UNWRAPPING_AVERAGE_LATENCY_MS = 434 + SERVER_SIDE_UNWRAPPING_CALLOUTS = 435 + SERVER_SIDE_UNWRAPPING_EMPTY_RESPONSES = 436 + SERVER_SIDE_UNWRAPPING_ERROR_RESPONSES = 437 + SERVER_SIDE_UNWRAPPING_SUCCESSFUL_RESPONSES = 438 + SERVER_SIDE_UNWRAPPING_TIMEOUTS = 439 + SESSIONS = 239 + TAG_LOAD_TO_FIRST_AD_REQUEST_0_500_PERCENT = 455 + TAG_LOAD_TO_FIRST_AD_REQUEST_1000_2000_PERCENT = 457 + TAG_LOAD_TO_FIRST_AD_REQUEST_2000_4000_PERCENT = 458 + TAG_LOAD_TO_FIRST_AD_REQUEST_4000_8000_PERCENT = 459 + TAG_LOAD_TO_FIRST_AD_REQUEST_500_1000_PERCENT = 456 + TAG_LOAD_TO_FIRST_AD_REQUEST_GT_8000_PERCENT = 460 + TARGETED_CLICKS = 276 + TARGETED_IMPRESSIONS = 277 + UNFILLED_IMPRESSIONS = 45 + UNIQUE_VISITORS = 417 + UNLOADED_IMPRESSIONS_DUE_TO_CPU = 408 + UNLOADED_IMPRESSIONS_DUE_TO_NETWORK = 406 + UNMATCHED_AD_REQUESTS = 43 + UNVIEWED_REASON_OTHER_PERCENT = 550 + UNVIEWED_REASON_SLOT_NEVER_ENTERED_VIEWPORT_PERCENT = 553 + UNVIEWED_REASON_USER_SCROLLED_BEFORE_AD_FILLED_PERCENT = 551 + UNVIEWED_REASON_USER_SCROLLED_BEFORE_AD_LOADED_PERCENT = 552 + UNVIEWED_REASON_USER_SCROLLED_BEFORE_ONE_SECOND_PERCENT = 549 + USER_ENGAGEMENT_DURATION_IN_SECONDS = 240 + USER_MESSAGES_AD_BLOCKING_EXTENSION_RATE = 486 + USER_MESSAGES_AD_BLOCKING_RECOVERY_ALLOWLISTED_COUNT = 487 + USER_MESSAGES_AD_BLOCKING_RECOVERY_MESSAGES_SHOWN = 488 + USER_MESSAGES_ALLOW_ADS_PAGEVIEWS = 489 + USER_MESSAGES_CCPA_MESSAGES_SHOWN = 490 + USER_MESSAGES_IDFA_ATT_ALERTS_SHOWN = 491 + USER_MESSAGES_IDFA_ATT_CONSENT = 492 + USER_MESSAGES_IDFA_ATT_CONSENT_RATE = 493 + USER_MESSAGES_IDFA_ATT_DECLINE_CONSENT = 494 + USER_MESSAGES_IDFA_ATT_DECLINE_RATE = 495 + USER_MESSAGES_IDFA_EXPLAINERS_SHOWN = 496 + USER_MESSAGES_IDFA_IAB_MESSAGES_SHOWN = 497 + USER_MESSAGES_IDFA_NO_DECISION = 498 + USER_MESSAGES_OFFERWALL_MESSAGES_SHOWN = 121 + USER_MESSAGES_OFFERWALL_SUCCESSFUL_ENGAGEMENTS = 122 + USER_MESSAGES_POST_OFFERWALL_PAGEVIEWS = 499 + USER_MESSAGES_TOTAL_ESTIMATED_REVENUE = 500 + USER_MESSAGES_UPTC_MESSAGES_SHOWN = 501 + USER_MESSAGES_UPTC_PERSONALIZATION_OPT_OUT_RATIO = 502 + VIDEO_ERROR_100_COUNT = 180 + VIDEO_ERROR_101_COUNT = 181 + VIDEO_ERROR_102_COUNT = 182 + VIDEO_ERROR_200_COUNT = 183 + VIDEO_ERROR_201_COUNT = 184 + VIDEO_ERROR_202_COUNT = 185 + VIDEO_ERROR_203_COUNT = 186 + VIDEO_ERROR_300_COUNT = 187 + VIDEO_ERROR_301_COUNT = 188 + VIDEO_ERROR_302_COUNT = 189 + VIDEO_ERROR_303_COUNT = 190 + VIDEO_ERROR_400_COUNT = 191 + VIDEO_ERROR_401_COUNT = 192 + VIDEO_ERROR_402_COUNT = 193 + VIDEO_ERROR_403_COUNT = 194 + VIDEO_ERROR_405_COUNT = 195 + VIDEO_ERROR_406_COUNT = 196 + VIDEO_ERROR_407_COUNT = 197 + VIDEO_ERROR_408_COUNT = 198 + VIDEO_ERROR_409_COUNT = 199 + VIDEO_ERROR_410_COUNT = 200 + VIDEO_ERROR_500_COUNT = 201 + VIDEO_ERROR_501_COUNT = 202 + VIDEO_ERROR_502_COUNT = 203 + VIDEO_ERROR_503_COUNT = 204 + VIDEO_ERROR_600_COUNT = 205 + VIDEO_ERROR_601_COUNT = 206 + VIDEO_ERROR_602_COUNT = 207 + VIDEO_ERROR_603_COUNT = 208 + VIDEO_ERROR_604_COUNT = 209 + VIDEO_ERROR_900_COUNT = 210 + VIDEO_ERROR_901_COUNT = 211 + VIDEO_INTERACTION_AVERAGE_INTERACTION_RATE = 92 + VIDEO_INTERACTION_COLLAPSES = 93 + VIDEO_INTERACTION_EXPANDS = 95 + VIDEO_INTERACTION_FULL_SCREENS = 96 + VIDEO_INTERACTION_MUTES = 97 + VIDEO_INTERACTION_PAUSES = 98 + VIDEO_INTERACTION_RESUMES = 99 + VIDEO_INTERACTION_REWINDS = 100 + VIDEO_INTERACTION_UNMUTES = 101 + VIDEO_INTERACTION_VIDEO_SKIPS = 102 + VIDEO_MONETIZABLE_CONTENT_VIEWS = 601 + VIDEO_REAL_TIME_CREATIVE_SERVES = 139 + VIDEO_REAL_TIME_ERROR_100_COUNT = 143 + VIDEO_REAL_TIME_ERROR_101_COUNT = 144 + VIDEO_REAL_TIME_ERROR_102_COUNT = 145 + VIDEO_REAL_TIME_ERROR_200_COUNT = 146 + VIDEO_REAL_TIME_ERROR_201_COUNT = 147 + VIDEO_REAL_TIME_ERROR_202_COUNT = 148 + VIDEO_REAL_TIME_ERROR_203_COUNT = 149 + VIDEO_REAL_TIME_ERROR_300_COUNT = 150 + VIDEO_REAL_TIME_ERROR_301_COUNT = 151 + VIDEO_REAL_TIME_ERROR_302_COUNT = 152 + VIDEO_REAL_TIME_ERROR_303_COUNT = 153 + VIDEO_REAL_TIME_ERROR_400_COUNT = 154 + VIDEO_REAL_TIME_ERROR_401_COUNT = 155 + VIDEO_REAL_TIME_ERROR_402_COUNT = 156 + VIDEO_REAL_TIME_ERROR_403_COUNT = 157 + VIDEO_REAL_TIME_ERROR_405_COUNT = 158 + VIDEO_REAL_TIME_ERROR_406_COUNT = 159 + VIDEO_REAL_TIME_ERROR_407_COUNT = 160 + VIDEO_REAL_TIME_ERROR_408_COUNT = 161 + VIDEO_REAL_TIME_ERROR_409_COUNT = 162 + VIDEO_REAL_TIME_ERROR_410_COUNT = 163 + VIDEO_REAL_TIME_ERROR_500_COUNT = 164 + VIDEO_REAL_TIME_ERROR_501_COUNT = 165 + VIDEO_REAL_TIME_ERROR_502_COUNT = 166 + VIDEO_REAL_TIME_ERROR_503_COUNT = 167 + VIDEO_REAL_TIME_ERROR_600_COUNT = 168 + VIDEO_REAL_TIME_ERROR_601_COUNT = 169 + VIDEO_REAL_TIME_ERROR_602_COUNT = 170 + VIDEO_REAL_TIME_ERROR_603_COUNT = 171 + VIDEO_REAL_TIME_ERROR_604_COUNT = 172 + VIDEO_REAL_TIME_ERROR_900_COUNT = 173 + VIDEO_REAL_TIME_ERROR_901_COUNT = 174 + VIDEO_REAL_TIME_IMPRESSIONS = 138 + VIDEO_REAL_TIME_MATCHED_QUERIES = 140 + VIDEO_REAL_TIME_TOTAL_ERROR_COUNT = 175 + VIDEO_REAL_TIME_TOTAL_QUERIES = 142 + VIDEO_REAL_TIME_UNMATCHED_QUERIES = 141 + VIDEO_VIEWERSHIP_AUTO_PLAYS = 103 + VIDEO_VIEWERSHIP_AVERAGE_VIEW_RATE = 104 + VIDEO_VIEWERSHIP_AVERAGE_VIEW_TIME = 105 + VIDEO_VIEWERSHIP_CLICK_TO_PLAYS = 106 + VIDEO_VIEWERSHIP_COMPLETES = 107 + VIDEO_VIEWERSHIP_COMPLETION_RATE = 108 + VIDEO_VIEWERSHIP_ENGAGED_VIEWS = 109 + VIDEO_VIEWERSHIP_FIRST_QUARTILES = 110 + VIDEO_VIEWERSHIP_MIDPOINTS = 111 + VIDEO_VIEWERSHIP_SKIP_BUTTONS_SHOWN = 112 + VIDEO_VIEWERSHIP_STARTS = 113 + VIDEO_VIEWERSHIP_THIRD_QUARTILES = 114 + VIDEO_VIEWERSHIP_TOTAL_ERROR_COUNT = 115 + VIDEO_VIEWERSHIP_TOTAL_ERROR_RATE = 94 + VIDEO_VIEWERSHIP_VIDEO_LENGTH = 116 + VIDEO_VIEWERSHIP_VIEW_THROUGH_RATE = 117 + YIELD_GROUP_AUCTIONS_WON = 80 + YIELD_GROUP_BIDS = 81 + YIELD_GROUP_BIDS_IN_AUCTION = 82 + YIELD_GROUP_CALLOUTS = 83 + YIELD_GROUP_ESTIMATED_CPM = 88 + YIELD_GROUP_ESTIMATED_REVENUE = 87 + YIELD_GROUP_IMPRESSIONS = 85 + YIELD_GROUP_MEDIATION_FILL_RATE = 89 + YIELD_GROUP_MEDIATION_MATCHED_QUERIES = 86 + YIELD_GROUP_MEDIATION_PASSBACKS = 118 + YIELD_GROUP_MEDIATION_THIRD_PARTY_ECPM = 90 + YIELD_GROUP_REVENUE_PAID_THROUGH_MCM_AUTOPAYMENT = 215 + YIELD_GROUP_SUCCESSFUL_RESPONSES = 84 + + class TimePeriodColumn(proto.Enum): + r"""Valid time period columns. + + Values: + TIME_PERIOD_COLUMN_UNSPECIFIED (0): + Default value. Report will have no time + period column. + TIME_PERIOD_COLUMN_DATE (1): + A column for each date in the report. + TIME_PERIOD_COLUMN_WEEK (2): + A column for each week in the report. + TIME_PERIOD_COLUMN_MONTH (3): + A column for each month in the report. + TIME_PERIOD_COLUMN_QUARTER (4): + A column for each quarter in the report. + """ + TIME_PERIOD_COLUMN_UNSPECIFIED = 0 + TIME_PERIOD_COLUMN_DATE = 1 + TIME_PERIOD_COLUMN_WEEK = 2 + TIME_PERIOD_COLUMN_MONTH = 3 + TIME_PERIOD_COLUMN_QUARTER = 4 + + class MetricValueType(proto.Enum): + r"""Possible metric value types to add. + + Values: + PRIMARY (0): + The values for the primary date_range. + PRIMARY_PERCENT_OF_TOTAL (1): + Each metrics' percent of the total for the primary + date_range. + COMPARISON (2): + The values for the comparison_date_range. + COMPARISON_PERCENT_OF_TOTAL (3): + Each metrics' percent of the total for the + comparison_date_range. + ABSOLUTE_CHANGE (4): + The absolute change between the primary and + comparison date ranges. + RELATIVE_CHANGE (5): + The relative change between the primary and + comparison date ranges. + """ + PRIMARY = 0 + PRIMARY_PERCENT_OF_TOTAL = 1 + COMPARISON = 2 + COMPARISON_PERCENT_OF_TOTAL = 3 + ABSOLUTE_CHANGE = 4 + RELATIVE_CHANGE = 5 + + class TimeZoneSource(proto.Enum): + r"""The source to determine the time zone for the report. + + Values: + TIME_ZONE_SOURCE_UNSPECIFIED (0): + Unspecified default value. + PUBLISHER (1): + Use the publisher's time zone in network + settings. + AD_EXCHANGE (2): + Use the time zone of the ad exchange. + Only compatible with Ad Exchange dimensions and + metrics. + UTC (3): + Use UTC time zone. + Only compatible with Revenue Verification + reports. + PROVIDED (4): + Use the time zone provided in the ReportDefinition.time_zone + field. Has limited dimension and metric compatibility + compared with PUBLISHER, and reports may take longer to run + since the dates are dynamically calculated at request time. + """ + TIME_ZONE_SOURCE_UNSPECIFIED = 0 + PUBLISHER = 1 + AD_EXCHANGE = 2 + UTC = 3 + PROVIDED = 4 + + class Field(proto.Message): + r"""A dimension or a metric in a report. + + 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.admanager_v1.types.ReportDefinition.Dimension): + The dimension this field represents. + + This field is a member of `oneof`_ ``field``. + metric (google.ads.admanager_v1.types.ReportDefinition.Metric): + The metric this field represents. + + This field is a member of `oneof`_ ``field``. + """ + + dimension: "ReportDefinition.Dimension" = proto.Field( + proto.ENUM, + number=1, + oneof="field", + enum="ReportDefinition.Dimension", + ) + metric: "ReportDefinition.Metric" = proto.Field( + proto.ENUM, + number=2, + oneof="field", + enum="ReportDefinition.Metric", + ) + + class DateRange(proto.Message): + r"""A date range for a report. + + 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: + fixed (google.ads.admanager_v1.types.ReportDefinition.DateRange.FixedDateRange): + A fixed date range. + + This field is a member of `oneof`_ ``date_range_type``. + relative (google.ads.admanager_v1.types.ReportDefinition.DateRange.RelativeDateRange): + A relative date range. + + This field is a member of `oneof`_ ``date_range_type``. + """ + + class RelativeDateRange(proto.Enum): + r"""Options for relative date ranges. + + Values: + RELATIVE_DATE_RANGE_UNSPECIFIED (0): + Default value. This value is unused. + TODAY (1): + The date the report is run. + YESTERDAY (2): + The date a day before the date that the + report is run. + THIS_WEEK (3): + The full week in which this report is run. + Could include dates in the future. + THIS_WEEK_TO_DATE (29): + From the beginning of the calendar week + (Monday to Sunday) in which the up to and + including the day the report is run. + THIS_MONTH (4): + The full month in which this report is run. + Could include dates in the future. + THIS_MONTH_TO_DATE (26): + From the beginning of the calendar month in + which the report is run, to up to and including + the day the report is run. + THIS_QUARTER (5): + The full quarter in which this report is run. + Could include dates in the future. + THIS_QUARTER_TO_DATE (27): + From the beginning of the calendar quarter in + which the report is run, up to and including the + day the report is run. + THIS_YEAR (6): + The full year in which this report is run. + Could include dates in the future. + THIS_YEAR_TO_DATE (28): + From the beginning of the calendar year in + which the report is run, to up to and including + the day the report is run. + LAST_WEEK (7): + The entire previous calendar week, Monday to + Sunday (inclusive), preceding the calendar week + the report is run. + LAST_MONTH (8): + The entire previous calendar month preceding + the calendar month the report is run. + LAST_QUARTER (9): + The entire previous calendar quarter + preceding the calendar quarter the report is + run. + LAST_YEAR (10): + The entire previous calendar year preceding + the calendar year the report is run. + LAST_7_DAYS (11): + The 7 days preceding the day the report is + run. + LAST_30_DAYS (12): + The 30 days preceding the day the report is + run. + LAST_60_DAYS (13): + The 60 days preceding the day the report is + run. + LAST_90_DAYS (14): + The 90 days preceding the day the report is + run. + LAST_180_DAYS (15): + The 180 days preceding the day the report is + run. + LAST_360_DAYS (16): + The 360 days preceding the day the report is + run. + LAST_365_DAYS (17): + The 365 days preceding the day the report is + run. + LAST_3_MONTHS (18): + The entire previous 3 calendar months + preceding the calendar month the report is run. + LAST_6_MONTHS (19): + The entire previous 6 calendar months + preceding the calendar month the report is run. + LAST_12_MONTHS (20): + The entire previous 6 calendar months + preceding the calendar month the report is run. + ALL_AVAILABLE (21): + From 3 years before the report is run, to the + day before the report is run, inclusive. + TOMORROW (30): + The date a day after the date that the report + is run. + NEXT_90_DAYS (31): + The 90 days following the day the report is + run. + NEXT_MONTH (32): + The entire calendar month following the + calendar month the report is run. + NEXT_3_MONTHS (33): + The entire 3 calendar months following the + calendar month the report is run. + NEXT_12_MONTHS (34): + The entire 12 calendar months following the + calendar month the report is run. + NEXT_WEEK (35): + The entire calendar week, Monday to Sunday + (inclusive), following the calendar week the + report is run. + NEXT_QUARTER (36): + The entire calendar quarter following the + calendar quarter the report is run. + TO_END_OF_NEXT_MONTH (37): + From the date a day after the date that the + report is run, to the end of the calendar month + following the calendar month the report is run. + PREVIOUS_PERIOD (22): + Only valid when used in the comparison_date_range field. The + complete period preceding the date period provided in + date_range. + + In the case where date_range is a FixedDateRange of N days, + this will be a period of N days where the end date is the + date preceding the start date of the date_range. + + In the case where date_range is a RelativeDateRange, this + will be a period of the same timeframe preceding the + date_range. In the case where the date_range does not + capture the full period because a report is run in the + middle of that period, this will still be the full preceding + period. For example, if date_range is THIS_WEEK, but the + report is run on a Wednesday, THIS_WEEK will be Monday - + Wednesday, but PREVIOUS_PERIOD will be Monday - Sunday. + SAME_PERIOD_PREVIOUS_YEAR (24): + Only valid when used in the comparison_date_range field. The + period starting 1 year prior to the date period provided in + date_range. + + In the case where date_range is a FixedDateRange, this will + be a date range starting 1 year prior to the date_range + start date and ending 1 year prior to the date_range end + date. + + In the case where date_range is a RelativeDateRange, this + will be a period of the same timeframe exactly 1 year prior + to the date_range. In the case where the date_range does not + capture the full period because a report is run in the + middle of that period, this will still be the full period 1 + year prior. For example, if date range is THIS_WEEK, but the + report is run on a Wednesday, THIS_WEEK will be Monday - + Wednesday, but SAME_PERIOD_PREVIOUS_YEAR will be Monday - + Sunday. + """ + RELATIVE_DATE_RANGE_UNSPECIFIED = 0 + TODAY = 1 + YESTERDAY = 2 + THIS_WEEK = 3 + THIS_WEEK_TO_DATE = 29 + THIS_MONTH = 4 + THIS_MONTH_TO_DATE = 26 + THIS_QUARTER = 5 + THIS_QUARTER_TO_DATE = 27 + THIS_YEAR = 6 + THIS_YEAR_TO_DATE = 28 + LAST_WEEK = 7 + LAST_MONTH = 8 + LAST_QUARTER = 9 + LAST_YEAR = 10 + LAST_7_DAYS = 11 + LAST_30_DAYS = 12 + LAST_60_DAYS = 13 + LAST_90_DAYS = 14 + LAST_180_DAYS = 15 + LAST_360_DAYS = 16 + LAST_365_DAYS = 17 + LAST_3_MONTHS = 18 + LAST_6_MONTHS = 19 + LAST_12_MONTHS = 20 + ALL_AVAILABLE = 21 + TOMORROW = 30 + NEXT_90_DAYS = 31 + NEXT_MONTH = 32 + NEXT_3_MONTHS = 33 + NEXT_12_MONTHS = 34 + NEXT_WEEK = 35 + NEXT_QUARTER = 36 + TO_END_OF_NEXT_MONTH = 37 + PREVIOUS_PERIOD = 22 + SAME_PERIOD_PREVIOUS_YEAR = 24 + + class FixedDateRange(proto.Message): + r"""A date range between two fixed dates (inclusive of end date). + + Attributes: + start_date (google.type.date_pb2.Date): + Required. The start date of this date range. + end_date (google.type.date_pb2.Date): + Required. The end date (inclusive) of this + date range. + """ + + start_date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=1, + message=date_pb2.Date, + ) + end_date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=2, + message=date_pb2.Date, + ) + + fixed: "ReportDefinition.DateRange.FixedDateRange" = proto.Field( + proto.MESSAGE, + number=1, + oneof="date_range_type", + message="ReportDefinition.DateRange.FixedDateRange", + ) + relative: "ReportDefinition.DateRange.RelativeDateRange" = proto.Field( + proto.ENUM, + number=2, + oneof="date_range_type", + enum="ReportDefinition.DateRange.RelativeDateRange", + ) + + class Filter(proto.Message): + r"""A filter over one or more fields. + + 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: + field_filter (google.ads.admanager_v1.types.ReportDefinition.Filter.FieldFilter): + A filter on a single field. + + This field is a member of `oneof`_ ``type``. + not_filter (google.ads.admanager_v1.types.ReportDefinition.Filter): + A filter whose result is negated. + + This field is a member of `oneof`_ ``type``. + and_filter (google.ads.admanager_v1.types.ReportDefinition.Filter.FilterList): + A list of filters whose results are AND-ed. + + This field is a member of `oneof`_ ``type``. + or_filter (google.ads.admanager_v1.types.ReportDefinition.Filter.FilterList): + A list of filters whose results are OR-ed. + + This field is a member of `oneof`_ ``type``. + """ + + class Operation(proto.Enum): + r"""Supported filter operations. + + Values: + IN (0): + For scalar operands, checks if the operand is + in the set of provided filter values. + + For list operands, checks if any element in the + operand is in the set of provided filter values. + + Default value. + NOT_IN (1): + For scalar operands, checks that the operand + is not in the set of provided filter values. + + For list operands, checks that none of the + elements in the operand is in the set of + provided filter values. + CONTAINS (2): + For scalar string operands, checks if the + operand contains any of the provided filter + substrings. + + For string list operands, checks if any string + in the operand contains any of the provided + filter substrings. + NOT_CONTAINS (3): + For scalar string operands, checks that the + operand contains none of the provided filter + substrings. + + For string list operands, checks that none of + the strings in the operand contain none of the + provided filter substrings. + LESS_THAN (4): + Operand is less than the provided filter + value. + LESS_THAN_EQUALS (5): + Operand is less than or equal to provided + filter value. + GREATER_THAN (6): + Operand is greater than provided filter + value. + GREATER_THAN_EQUALS (7): + Operand is greater than or equal to provided + filter value. + BETWEEN (8): + Operand is between provided filter values. + MATCHES (9): + Operand matches against a regular expression + or set of regular expressions (one must match). + NOT_MATCHES (10): + Operand negative matches against a regular + expression or set of regular expressions (none + must match). + """ + IN = 0 + NOT_IN = 1 + CONTAINS = 2 + NOT_CONTAINS = 3 + LESS_THAN = 4 + LESS_THAN_EQUALS = 5 + GREATER_THAN = 6 + GREATER_THAN_EQUALS = 7 + BETWEEN = 8 + MATCHES = 9 + NOT_MATCHES = 10 + + class FieldFilter(proto.Message): + r"""A filter on a specific field. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + field (google.ads.admanager_v1.types.ReportDefinition.Field): + Required. The field to filter on. + operation (google.ads.admanager_v1.types.ReportDefinition.Filter.Operation): + Required. The operation of this filter. + values (MutableSequence[google.ads.admanager_v1.types.ReportValue]): + Required. Values to filter to. + slice_ (google.ads.admanager_v1.types.ReportDefinition.Slice): + Optional. Use to filter on a specific slice + of data. + + This field is a member of `oneof`_ ``_slice``. + time_period_index (int): + Optional. When using time period columns, use + this to filter on a specific column. + + This field is a member of `oneof`_ ``_time_period_index``. + metric_value_type (google.ads.admanager_v1.types.ReportDefinition.MetricValueType): + Optional. Use to specify which metric value + type to filter on. Defaults to PRIMARY. + + This field is a member of `oneof`_ ``_metric_value_type``. + """ + + field: "ReportDefinition.Field" = proto.Field( + proto.MESSAGE, + number=1, + message="ReportDefinition.Field", + ) + operation: "ReportDefinition.Filter.Operation" = proto.Field( + proto.ENUM, + number=2, + enum="ReportDefinition.Filter.Operation", + ) + values: MutableSequence[report_value.ReportValue] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=report_value.ReportValue, + ) + slice_: "ReportDefinition.Slice" = proto.Field( + proto.MESSAGE, + number=4, + optional=True, + message="ReportDefinition.Slice", + ) + time_period_index: int = proto.Field( + proto.INT32, + number=5, + optional=True, + ) + metric_value_type: "ReportDefinition.MetricValueType" = proto.Field( + proto.ENUM, + number=6, + optional=True, + enum="ReportDefinition.MetricValueType", + ) + + class FilterList(proto.Message): + r"""A list of filters. + + Attributes: + filters (MutableSequence[google.ads.admanager_v1.types.ReportDefinition.Filter]): + Required. A list of filters. + """ + + filters: MutableSequence["ReportDefinition.Filter"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="ReportDefinition.Filter", + ) + + field_filter: "ReportDefinition.Filter.FieldFilter" = proto.Field( + proto.MESSAGE, + number=1, + oneof="type", + message="ReportDefinition.Filter.FieldFilter", + ) + not_filter: "ReportDefinition.Filter" = proto.Field( + proto.MESSAGE, + number=2, + oneof="type", + message="ReportDefinition.Filter", + ) + and_filter: "ReportDefinition.Filter.FilterList" = proto.Field( + proto.MESSAGE, + number=3, + oneof="type", + message="ReportDefinition.Filter.FilterList", + ) + or_filter: "ReportDefinition.Filter.FilterList" = proto.Field( + proto.MESSAGE, + number=4, + oneof="type", + message="ReportDefinition.Filter.FilterList", + ) + + class Sort(proto.Message): + r"""Represents a sorting in a report. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + field (google.ads.admanager_v1.types.ReportDefinition.Field): + Required. A field (dimension or metric) to + sort by. + descending (bool): + Optional. The sort order. If true the sort + will be descending. + slice_ (google.ads.admanager_v1.types.ReportDefinition.Slice): + Optional. Use to sort on a specific slice of + data. + + This field is a member of `oneof`_ ``_slice``. + time_period_index (int): + Optional. When using time period columns, use + this to sort on a specific column. + + This field is a member of `oneof`_ ``_time_period_index``. + metric_value_type (google.ads.admanager_v1.types.ReportDefinition.MetricValueType): + Optional. Use to specify which metric value + type to sort on. Defaults to PRIMARY. + + This field is a member of `oneof`_ ``_metric_value_type``. + """ + + field: "ReportDefinition.Field" = proto.Field( + proto.MESSAGE, + number=1, + message="ReportDefinition.Field", + ) + descending: bool = proto.Field( + proto.BOOL, + number=2, + ) + slice_: "ReportDefinition.Slice" = proto.Field( + proto.MESSAGE, + number=3, + optional=True, + message="ReportDefinition.Slice", + ) + time_period_index: int = proto.Field( + proto.INT32, + number=4, + optional=True, + ) + metric_value_type: "ReportDefinition.MetricValueType" = proto.Field( + proto.ENUM, + number=5, + optional=True, + enum="ReportDefinition.MetricValueType", + ) + + class Slice(proto.Message): + r"""Use to specify a slice of data. + + For example, in a report, to focus on just data from the US, specify + ``COUNTRY_NAME`` for dimension and value: ``"United States"``. + + Attributes: + dimension (google.ads.admanager_v1.types.ReportDefinition.Dimension): + Required. The dimension to slice on. + value (google.ads.admanager_v1.types.ReportValue): + Required. The value of the dimension. + """ + + dimension: "ReportDefinition.Dimension" = proto.Field( + proto.ENUM, + number=1, + enum="ReportDefinition.Dimension", + ) + value: report_value.ReportValue = proto.Field( + proto.MESSAGE, + number=2, + message=report_value.ReportValue, + ) + + class Flag(proto.Message): + r"""A flag for a report. Flags are used show if certain thresholds are + met. Result rows that match the filter will have the corresponding + [MetricValueGroup.flagValues][MetricValueGroup] index set to true. + For more information about flags see: + https://support.google.com/admanager/answer/15079975 + + Attributes: + filters (MutableSequence[google.ads.admanager_v1.types.ReportDefinition.Filter]): + Required. Filters to apply for the flag. + name (str): + Optional. Name of the flag. + The flag names RED, YELLOW, GREEN, BLUE, PURPLE, + and GREY correspond to the colored flags that + appear in the UI. The UI won't display flags + with other names, but they are available for use + by API clients. + """ + + filters: MutableSequence["ReportDefinition.Filter"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="ReportDefinition.Filter", + ) + name: str = proto.Field( + proto.STRING, + number=2, + ) + + dimensions: MutableSequence[Dimension] = proto.RepeatedField( + proto.ENUM, + number=1, + enum=Dimension, + ) + metrics: MutableSequence[Metric] = proto.RepeatedField( + proto.ENUM, + number=2, + enum=Metric, + ) + filters: MutableSequence[Filter] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=Filter, + ) + time_zone_source: TimeZoneSource = proto.Field( + proto.ENUM, + number=20, + enum=TimeZoneSource, + ) + time_zone: str = proto.Field( + proto.STRING, + number=4, + ) + currency_code: str = proto.Field( + proto.STRING, + number=5, + ) + date_range: DateRange = proto.Field( + proto.MESSAGE, + number=6, + message=DateRange, + ) + comparison_date_range: DateRange = proto.Field( + proto.MESSAGE, + number=9, + optional=True, + message=DateRange, + ) + custom_dimension_key_ids: MutableSequence[int] = proto.RepeatedField( + proto.INT64, + number=7, + ) + line_item_custom_field_ids: MutableSequence[int] = proto.RepeatedField( + proto.INT64, + number=11, + ) + order_custom_field_ids: MutableSequence[int] = proto.RepeatedField( + proto.INT64, + number=12, + ) + creative_custom_field_ids: MutableSequence[int] = proto.RepeatedField( + proto.INT64, + number=13, + ) + report_type: ReportType = proto.Field( + proto.ENUM, + number=8, + enum=ReportType, + ) + time_period_column: TimePeriodColumn = proto.Field( + proto.ENUM, + number=10, + enum=TimePeriodColumn, + ) + flags: MutableSequence[Flag] = proto.RepeatedField( + proto.MESSAGE, + number=14, + message=Flag, + ) + sorts: MutableSequence[Sort] = proto.RepeatedField( + proto.MESSAGE, + number=15, + message=Sort, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/report_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/report_messages.py index 4070c5db2626..e65aa9ce3e31 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/report_messages.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/report_messages.py @@ -23,13 +23,15 @@ from google.type import timeofday_pb2 # type: ignore import proto # type: ignore +from google.ads.admanager_v1.types import report_definition as gaa_report_definition +from google.ads.admanager_v1.types import report_value + __protobuf__ = proto.module( package="google.ads.admanager.v1", manifest={ "Report", - "ReportDefinition", + "ReportDataTable", "ScheduleOptions", - "Schedule", }, ) @@ -60,3378 +62,19 @@ class Report(proto.Message): locale (str): Output only. The locale of this report. Locale is set from the user's locale at the time - of the request. Locale can not be modified. + of the request. Locale can't be modified. schedule_options (google.ads.admanager_v1.types.ScheduleOptions): Optional. The schedule options of this report. """ - class TimePeriodColumn(proto.Enum): - r"""Valid time period columns. - - Values: - TIME_PERIOD_COLUMN_UNSPECIFIED (0): - Default value. Report will have no time - period column. - TIME_PERIOD_COLUMN_DATE (1): - A column for each date in the report. - TIME_PERIOD_COLUMN_WEEK (2): - A column for each week in the report. - TIME_PERIOD_COLUMN_MONTH (3): - A column for each month in the report. - TIME_PERIOD_COLUMN_QUARTER (4): - A column for each quarter in the report. - """ - TIME_PERIOD_COLUMN_UNSPECIFIED = 0 - TIME_PERIOD_COLUMN_DATE = 1 - TIME_PERIOD_COLUMN_WEEK = 2 - TIME_PERIOD_COLUMN_MONTH = 3 - TIME_PERIOD_COLUMN_QUARTER = 4 - - class Dimension(proto.Enum): - r"""Reporting dimensions. - - Values: - DIMENSION_UNSPECIFIED (0): - Default value. This value is unused. - ADVERTISER_DOMAIN_NAME (242): - The domain name of the advertiser. - ADVERTISER_EXTERNAL_ID (228): - The ID used in an external system for - advertiser identification - ADVERTISER_ID (131): - The ID of an advertiser company assigned to - an order - ADVERTISER_LABELS (230): - Labels applied to the advertiser - can be used for either competitive exclusion or - ad exclusion - ADVERTISER_LABEL_IDS (229): - Label ids applied to the advertiser - can be used for either competitive exclusion or - ad exclusion - ADVERTISER_NAME (132): - The name of an advertiser company assigned to - an order - ADVERTISER_PRIMARY_CONTACT (227): - The name of the contact associated with an - advertiser company - AD_LOCATION (390): - Shows an ENUM value describing whether a - given piece of publisher inventory was above - (ATF) or below the fold (BTF) of a page. - AD_LOCATION_NAME (391): - Shows a localized string describing whether a - given piece of publisher inventory was above - (ATF) or below the fold (BTF) of a page. - AD_UNIT_CODE (64): - The code of the ad unit where the ad was - requested. - AD_UNIT_CODE_LEVEL_1 (65): - The code of the first level ad unit of the ad - unit where the ad was requested. - AD_UNIT_CODE_LEVEL_10 (74): - The code of the tenth level ad unit of the ad - unit where the ad was requested. - AD_UNIT_CODE_LEVEL_11 (75): - The code of the eleventh level ad unit of the - ad unit where the ad was requested. - AD_UNIT_CODE_LEVEL_12 (76): - The code of the twelfth level ad unit of the - ad unit where the ad was requested. - AD_UNIT_CODE_LEVEL_13 (77): - The code of the thirteenth level ad unit of - the ad unit where the ad was requested. - AD_UNIT_CODE_LEVEL_14 (78): - The code of the fourteenth level ad unit of - the ad unit where the ad was requested. - AD_UNIT_CODE_LEVEL_15 (79): - The code of the fifteenth level ad unit of - the ad unit where the ad was requested. - AD_UNIT_CODE_LEVEL_16 (80): - The code of the sixteenth level ad unit of - the ad unit where the ad was requested. - AD_UNIT_CODE_LEVEL_2 (66): - The code of the second level ad unit of the - ad unit where the ad was requested. - AD_UNIT_CODE_LEVEL_3 (67): - The code of the third level ad unit of the ad - unit where the ad was requested. - AD_UNIT_CODE_LEVEL_4 (68): - The code of the fourth level ad unit of the - ad unit where the ad was requested. - AD_UNIT_CODE_LEVEL_5 (69): - The code of the fifth level ad unit of the ad - unit where the ad was requested. - AD_UNIT_CODE_LEVEL_6 (70): - The code of the sixth level ad unit of the ad - unit where the ad was requested. - AD_UNIT_CODE_LEVEL_7 (71): - The code of the seventh level ad unit of the - ad unit where the ad was requested. - AD_UNIT_CODE_LEVEL_8 (72): - The code of the eighth level ad unit of the - ad unit where the ad was requested. - AD_UNIT_CODE_LEVEL_9 (73): - The code of the ninth level ad unit of the ad - unit where the ad was requested. - AD_UNIT_DEPTH (101): - The depth of the ad unit's hierarchy - AD_UNIT_ID (25): - The ID of the ad unit where the ad was - requested. - AD_UNIT_ID_ALL_LEVEL (27): - The full hierarchy of ad unit IDs where the - ad was requested, from root to leaf, excluding - the root ad unit ID. - AD_UNIT_ID_LEVEL_1 (30): - The first level ad unit ID of the ad unit - where the ad was requested. - AD_UNIT_ID_LEVEL_10 (48): - The tenth level ad unit ID of the ad unit - where the ad was requested. - AD_UNIT_ID_LEVEL_11 (50): - The eleventh level ad unit ID of the ad unit - where the ad was requested. - AD_UNIT_ID_LEVEL_12 (52): - The twelfth level ad unit ID of the ad unit - where the ad was requested. - AD_UNIT_ID_LEVEL_13 (54): - The thirteenth level ad unit ID of the ad - unit where the ad was requested. - AD_UNIT_ID_LEVEL_14 (56): - The fourteenth level ad unit ID of the ad - unit where the ad was requested. - AD_UNIT_ID_LEVEL_15 (58): - The fifteenth level ad unit ID of the ad unit - where the ad was requested. - AD_UNIT_ID_LEVEL_16 (60): - The sixteenth level ad unit ID of the ad unit - where the ad was requested. - AD_UNIT_ID_LEVEL_2 (32): - The second level ad unit ID of the ad unit - where the ad was requested. - AD_UNIT_ID_LEVEL_3 (34): - The third level ad unit ID of the ad unit - where the ad was requested. - AD_UNIT_ID_LEVEL_4 (36): - The fourth level ad unit ID of the ad unit - where the ad was requested. - AD_UNIT_ID_LEVEL_5 (38): - The fifth level ad unit ID of the ad unit - where the ad was requested. - AD_UNIT_ID_LEVEL_6 (40): - The sixth level ad unit ID of the ad unit - where the ad was requested. - AD_UNIT_ID_LEVEL_7 (42): - The seventh level ad unit ID of the ad unit - where the ad was requested. - AD_UNIT_ID_LEVEL_8 (44): - The eighth level ad unit ID of the ad unit - where the ad was requested. - AD_UNIT_ID_LEVEL_9 (46): - The ninth level ad unit ID of the ad unit - where the ad was requested. - AD_UNIT_ID_TOP_LEVEL (142): - The top-level ad unit ID of the ad unit where - the ad was requested. - AD_UNIT_NAME (26): - The name of the ad unit where the ad was - requested. - AD_UNIT_NAME_ALL_LEVEL (29): - The full hierarchy of ad unit names where the - ad was requested, from root to leaf, excluding - the root ad unit name. - AD_UNIT_NAME_LEVEL_1 (31): - The first level ad unit name of the ad unit - where the ad was requested. - AD_UNIT_NAME_LEVEL_10 (49): - The tenth level ad unit name of the ad unit - where the ad was requested. - AD_UNIT_NAME_LEVEL_11 (51): - The eleventh level ad unit name of the ad - unit where the ad was requested. - AD_UNIT_NAME_LEVEL_12 (53): - The twelfth level ad unit name of the ad unit - where the ad was requested. - AD_UNIT_NAME_LEVEL_13 (55): - The thirteenth level ad unit name of the ad - unit where the ad was requested. - AD_UNIT_NAME_LEVEL_14 (57): - The fourteenth level ad unit name of the ad - unit where the ad was requested. - AD_UNIT_NAME_LEVEL_15 (59): - The fifteenth level ad unit name of the ad - unit where the ad was requested. - AD_UNIT_NAME_LEVEL_16 (61): - The sixteenth level ad unit name of the ad - unit where the ad was requested. - AD_UNIT_NAME_LEVEL_2 (33): - The second level ad unit name of the ad unit - where the ad was requested. - AD_UNIT_NAME_LEVEL_3 (35): - The third level ad unit name of the ad unit - where the ad was requested. - AD_UNIT_NAME_LEVEL_4 (37): - The fourth level ad unit name of the ad unit - where the ad was requested. - AD_UNIT_NAME_LEVEL_5 (39): - The fifth level ad unit name of the ad unit - where the ad was requested. - AD_UNIT_NAME_LEVEL_6 (41): - The sixth level ad unit name of the ad unit - where the ad was requested. - AD_UNIT_NAME_LEVEL_7 (43): - The seventh level ad unit name of the ad unit - where the ad was requested. - AD_UNIT_NAME_LEVEL_8 (45): - The eighth level ad unit name of the ad unit - where the ad was requested. - AD_UNIT_NAME_LEVEL_9 (47): - The ninth level ad unit name of the ad unit - where the ad was requested. - AD_UNIT_NAME_TOP_LEVEL (143): - The top-level ad unit name of the ad unit - where the ad was requested. - AD_UNIT_REWARD_AMOUNT (63): - The reward amount of the ad unit where the ad - was requested. - AD_UNIT_REWARD_TYPE (62): - The reward type of the ad unit where the ad - was requested. - AD_UNIT_STATUS (206): - The status of the ad unit - AD_UNIT_STATUS_NAME (207): - The name of the status of the ad unit - APP_VERSION (392): - The app version. - BACKFILL_ADVERTISER_EXTERNAL_ID (349): - The ID used in an external system for - advertiser identification - BACKFILL_ADVERTISER_ID (346): - The ID of an advertiser company assigned to a - backfill order - BACKFILL_ADVERTISER_LABELS (351): - Labels applied to the advertiser - can be used for either competitive exclusion or - ad exclusion - BACKFILL_ADVERTISER_LABEL_IDS (350): - Label ids applied to the advertiser - can be used for either competitive exclusion or - ad exclusion - BACKFILL_ADVERTISER_NAME (347): - The name of an advertiser company assigned to - a backfill order - BACKFILL_ADVERTISER_PRIMARY_CONTACT (348): - The name of the contact associated with an - advertiser company - BACKFILL_CREATIVE_BILLING_TYPE (378): - Enum value of Backfill creative billing type - BACKFILL_CREATIVE_BILLING_TYPE_NAME (379): - Localized string value of Backfill creative - billing type - BACKFILL_CREATIVE_CLICK_THROUGH_URL (376): - Represents the click-through URL of a - Backfill creative - BACKFILL_CREATIVE_ID (370): - The ID of a Backfill creative - BACKFILL_CREATIVE_NAME (371): - Backfill creative name - BACKFILL_CREATIVE_THIRD_PARTY_VENDOR (377): - Third party vendor name of a Backfill - creative - BACKFILL_CREATIVE_TYPE (374): - Enum value of Backfill creative type - BACKFILL_CREATIVE_TYPE_NAME (375): - Localized string name of Backfill creative - type - BACKFILL_LINE_ITEM_ARCHIVED (278): - Whether a Backfill line item is archived. - BACKFILL_LINE_ITEM_COMPANION_DELIVERY_OPTION (258): - Backfill line item comanion delivery option - ENUM value. - BACKFILL_LINE_ITEM_COMPANION_DELIVERY_OPTION_NAME (259): - Localized Backfill line item comanion - delivery option name. - BACKFILL_LINE_ITEM_COMPUTED_STATUS (296): - The computed status of the BackfillLineItem. - BACKFILL_LINE_ITEM_COMPUTED_STATUS_NAME (297): - The localized name of the computed status of - the BackfillLineItem. - BACKFILL_LINE_ITEM_CONTRACTED_QUANTITY (280): - The contracted units bought for the Backfill - line item. - BACKFILL_LINE_ITEM_COST_PER_UNIT (272): - The cost per unit of the Backfill line item. - BACKFILL_LINE_ITEM_COST_TYPE (264): - Backfill line item cost type ENUM value. - BACKFILL_LINE_ITEM_COST_TYPE_NAME (265): - Localized Backfill line item cost type name. - BACKFILL_LINE_ITEM_CREATIVE_END_DATE (381): - Represent the end date of a Backfill creative - associated with a Backfill line item - BACKFILL_LINE_ITEM_CREATIVE_ROTATION_TYPE (290): - The creative rotation type of the - BackfillLineItem. - BACKFILL_LINE_ITEM_CREATIVE_ROTATION_TYPE_NAME (291): - The localized name of the creative rotation - type of the BackfillLineItem. - BACKFILL_LINE_ITEM_CREATIVE_START_DATE (380): - Represent the start date of a Backfill - creative associated with a Backfill line item - BACKFILL_LINE_ITEM_CURRENCY_CODE (288): - The 3 letter currency code of the Backfill - line item - BACKFILL_LINE_ITEM_DELIVERY_INDICATOR (274): - The progress made for the delivery of the - Backfill line item. - BACKFILL_LINE_ITEM_DELIVERY_RATE_TYPE (292): - The delivery rate type of the - BackfillLineItem. - BACKFILL_LINE_ITEM_DELIVERY_RATE_TYPE_NAME (293): - The localized name of the delivery rate type - of the BackfillLineItem. - BACKFILL_LINE_ITEM_DISCOUNT_ABSOLUTE (294): - The discount of the BackfillLineItem in whole - units in the BackfillLineItem's currency code, - or if unspecified the Network's currency code. - BACKFILL_LINE_ITEM_DISCOUNT_PERCENTAGE (295): - The discount of the BackfillLineItem in - percentage. - BACKFILL_LINE_ITEM_END_DATE (267): - The end date of the Backfill line item. - BACKFILL_LINE_ITEM_END_DATE_TIME (269): - The end date and time of the Backfill line - item. - BACKFILL_LINE_ITEM_ENVIRONMENT_TYPE (302): - The ENUM value of the environment a Backfill - line item is targeting. - BACKFILL_LINE_ITEM_ENVIRONMENT_TYPE_NAME (257): - The localized name of the environment a - Backfill line item is targeting. - BACKFILL_LINE_ITEM_EXTERNAL_DEAL_ID (285): - The deal ID of the Backfill line item. Set - for Programmatic Direct campaigns. - BACKFILL_LINE_ITEM_EXTERNAL_ID (273): - The external ID of the Backfill line item. - BACKFILL_LINE_ITEM_FREQUENCY_CAP (303): - The frequency cap of the Backfill line item - (descriptive string). - BACKFILL_LINE_ITEM_ID (298): - Backfill line item ID. - BACKFILL_LINE_ITEM_LAST_MODIFIED_BY_APP (289): - The application that last modified the - Backfill line item. - BACKFILL_LINE_ITEM_LIFETIME_CLICKS (283): - The total number of clicks delivered of the - lifetime of the Backfill line item. - BACKFILL_LINE_ITEM_LIFETIME_IMPRESSIONS (282): - The total number of impressions delivered - over the lifetime of the Backfill line item. - BACKFILL_LINE_ITEM_LIFETIME_VIEWABLE_IMPRESSIONS (284): - The total number of viewable impressions - delivered over the lifetime of the Backfill line - item. - BACKFILL_LINE_ITEM_MAKEGOOD (276): - Whether or not the Backfill line item is - Makegood. Makegood refers to free inventory - offered to buyers to compensate for mistakes or - under-delivery in the original campaigns. - BACKFILL_LINE_ITEM_NAME (299): - Backfill line item name. - BACKFILL_LINE_ITEM_NON_CPD_BOOKED_REVENUE (286): - The cost of booking for the Backfill line - item (non-CPD). - BACKFILL_LINE_ITEM_OPTIMIZABLE (277): - Whether a Backfill line item is eligible for - opitimization. - BACKFILL_LINE_ITEM_PRIMARY_GOAL_TYPE (262): - Goal type ENUM value of the primary goal of - the Backfill line item. - BACKFILL_LINE_ITEM_PRIMARY_GOAL_TYPE_NAME (263): - Localized goal type name of the primary goal - of the Backfill line item. - BACKFILL_LINE_ITEM_PRIMARY_GOAL_UNIT_TYPE (260): - Unit type ENUM value of the primary goal of - the Backfill line item. - BACKFILL_LINE_ITEM_PRIMARY_GOAL_UNIT_TYPE_NAME (261): - Localized unit type name of the primary goal - of the Backfill line item. - BACKFILL_LINE_ITEM_PRIORITY (266): - The priority of this Backfill line item as a - value between 1 and 16. In general, a lower - priority means more serving priority for the - Backfill line item. - BACKFILL_LINE_ITEM_RESERVATION_STATUS (306): - ENUM value describing the state of inventory - reservation for the BackfillLineItem. - BACKFILL_LINE_ITEM_RESERVATION_STATUS_NAME (307): - Localized string describing the state of - inventory reservation for the BackfillLineItem. - BACKFILL_LINE_ITEM_START_DATE (268): - The start date of the Backfill line item. - BACKFILL_LINE_ITEM_START_DATE_TIME (270): - The start date and time of the Backfill line - item. - BACKFILL_LINE_ITEM_TYPE (300): - Backfill line item type ENUM value. - BACKFILL_LINE_ITEM_TYPE_NAME (301): - Localized Backfill line item type name. - BACKFILL_LINE_ITEM_UNLIMITED_END (271): - Whether the Backfill line item end time and - end date is set to effectively never end. - BACKFILL_LINE_ITEM_VALUE_COST_PER_UNIT (275): - The artificial cost per unit used by the Ad - server to help rank inventory. - BACKFILL_LINE_ITEM_WEB_PROPERTY_CODE (287): - The web property code used for dynamic - allocation Backfill line items. - BACKFILL_MASTER_COMPANION_CREATIVE_ID (372): - The ID of Backfill creative, includes regular - creatives, and master and companions in case of - creative sets - BACKFILL_MASTER_COMPANION_CREATIVE_NAME (373): - Name of Backfill creative, includes regular - creatives, and master and companions in case of - creative sets - BACKFILL_ORDER_AGENCY (313): - Backfill order agency. - BACKFILL_ORDER_AGENCY_ID (314): - Backfill order agency ID. - BACKFILL_ORDER_BOOKED_CPC (315): - Backfill order booked CPC. - BACKFILL_ORDER_BOOKED_CPM (316): - Backfill order booked CPM. - BACKFILL_ORDER_DELIVERY_STATUS (340): - Backfill order delivery status ENUM value. - BACKFILL_ORDER_DELIVERY_STATUS_NAME (341): - Backfill order delivery status localized - name. - BACKFILL_ORDER_END_DATE (317): - Backfill order end date. - BACKFILL_ORDER_END_DATE_TIME (319): - Backfill order end date and time. - BACKFILL_ORDER_EXTERNAL_ID (320): - Backfill order external ID. - BACKFILL_ORDER_ID (338): - Backfill order id. - BACKFILL_ORDER_LABELS (334): - Backfill order labels. - BACKFILL_ORDER_LABEL_IDS (335): - Backfill order labels IDs. - BACKFILL_ORDER_LIFETIME_CLICKS (322): - Backfill order lifetime clicks. - BACKFILL_ORDER_LIFETIME_IMPRESSIONS (323): - Backfill order lifetime impressions. - BACKFILL_ORDER_NAME (339): - Backfill order name. - BACKFILL_ORDER_PO_NUMBER (324): - Backfill order PO number. - BACKFILL_ORDER_PROGRAMMATIC (321): - Whether the Backfill order is programmatic. - BACKFILL_ORDER_SALESPERSON (325): - Backfill order sales person. - BACKFILL_ORDER_SECONDARY_SALESPEOPLE (329): - Backfill order secondary sales people. - BACKFILL_ORDER_SECONDARY_SALESPEOPLE_ID (328): - Backfill order secondary sales people ID. - BACKFILL_ORDER_SECONDARY_TRAFFICKERS (331): - Backfill order secondary traffickers. - BACKFILL_ORDER_SECONDARY_TRAFFICKERS_ID (330): - Backfill order secondary traffickers ID. - BACKFILL_ORDER_START_DATE (332): - Backfill order start date. - BACKFILL_ORDER_START_DATE_TIME (333): - Backfill order start date and time. - BACKFILL_ORDER_TRAFFICKER (326): - Backfill order trafficker. - BACKFILL_ORDER_TRAFFICKER_ID (327): - Backfill order trafficker ID. - BACKFILL_ORDER_UNLIMITED_END (318): - Whether the Backfill order end time and end - date is set to effectively never end. - BACKFILL_PROGRAMMATIC_BUYER_ID (336): - The ID of the buyer on a backfill - programmatic proposal. - BACKFILL_PROGRAMMATIC_BUYER_NAME (337): - The name of the buyer on a backfill - programmatic proposal. - BRANDING_TYPE (383): - The amount of information about the - Publisher's page sent to the buyer who purchased - the impressions. - BRANDING_TYPE_NAME (384): - The localized version of branding type, the - amount of information about the Publisher's page - sent to the buyer who purchased the impressions. - BROWSER_CATEGORY (119): - Browser category. - BROWSER_CATEGORY_NAME (120): - Browser category name. - BROWSER_ID (235): - The ID of the browser. - BROWSER_NAME (236): - The name of the browser. - CARRIER_ID (369): - Mobile carrier ID. - CARRIER_NAME (368): - Name of the mobile carrier. - CLASSIFIED_ADVERTISER_ID (133): - The ID of an advertiser, classified by - Google, associated with a creative transacted - CLASSIFIED_ADVERTISER_NAME (134): - The name of an advertiser, classified by - Google, associated with a creative transacted - CLASSIFIED_BRAND_ID (243): - ID of the brand, as classified by Google, - CLASSIFIED_BRAND_NAME (244): - Name of the brand, as classified by Google, - CONTENT_ID (246): - ID of the video content served. - CONTENT_NAME (247): - Name of the video content served. - COUNTRY_ID (11): - The criteria ID of the country in which the - ad served. - COUNTRY_NAME (12): - The name of the country in which the ad - served. - CREATIVE_BILLING_TYPE (366): - Enum value of creative billing type - CREATIVE_BILLING_TYPE_NAME (367): - Localized string value of creative billing - type - CREATIVE_CLICK_THROUGH_URL (174): - Represents the click-through URL of a - creative - CREATIVE_ID (138): - The ID of a creative - CREATIVE_NAME (139): - Creative name - CREATIVE_TECHNOLOGY (148): - Creative technology ENUM - CREATIVE_TECHNOLOGY_NAME (149): - Creative technology locallized name - CREATIVE_THIRD_PARTY_VENDOR (361): - Third party vendor name of a creative - CREATIVE_TYPE (344): - Enum value of creative type - CREATIVE_TYPE_NAME (345): - Localized string name of creative type - DATE (3): - Breaks down reporting data by date. - DAY_OF_WEEK (4): - Breaks down reporting data by day of the - week. Monday is 1 and 7 is Sunday. - DEMAND_CHANNEL (9): - Demand channel. - DEMAND_CHANNEL_NAME (10): - Demand channel name. - DEMAND_SUBCHANNEL (22): - Demand subchannel. - DEMAND_SUBCHANNEL_NAME (23): - Demand subchannel name. - DEVICE (226): - The device on which an ad was served. - DEVICE_CATEGORY (15): - The device category to which an ad is being - targeted. - DEVICE_CATEGORY_NAME (16): - The name of the category of device - (smartphone, feature phone, tablet, or desktop) - to which an ad is being targeted. - DEVICE_NAME (225): - The localized name of the device on which an - ad was served. - EXCHANGE_THIRD_PARTY_COMPANY_ID (185): - ID of the yield partner as classified by - Google - EXCHANGE_THIRD_PARTY_COMPANY_NAME (186): - Name of the yield partner as classified by - Google - FIRST_LOOK_PRICING_RULE_ID (248): - The ID of the first look pricing rule. - FIRST_LOOK_PRICING_RULE_NAME (249): - The name of the first look pricing rule. - HOUR (100): - Breaks down reporting data by hour in one - day. - INTERACTION_TYPE (223): - The interaction type of an ad. - INTERACTION_TYPE_NAME (224): - The localized name of the interaction type of - an ad. - INVENTORY_FORMAT (17): - Inventory format. - The format of the ad unit (e.g, banner) where - the ad was requested. - INVENTORY_FORMAT_NAME (18): - Inventory format name. - The format of the ad unit (e.g, banner) where - the ad was requested. - INVENTORY_TYPE (19): - Inventory type. - The kind of web page or device where the ad was - requested. - INVENTORY_TYPE_NAME (20): - Inventory type name. - The kind of web page or device where the ad was - requested. - IS_ADX_DIRECT (382): - Whether traffic is Adx Direct. - IS_FIRST_LOOK_DEAL (401): - Whether traffic is First Look. - KEY_VALUES_ID (214): - The Custom Targeting Value ID - KEY_VALUES_NAME (215): - The Custom Targeting Value formatted like - = - LINE_ITEM_ARCHIVED (188): - Whether a Line item is archived. - LINE_ITEM_COMPANION_DELIVERY_OPTION (204): - Line item comanion delivery option ENUM - value. - LINE_ITEM_COMPANION_DELIVERY_OPTION_NAME (205): - Localized line item comanion delivery option - name. - LINE_ITEM_COMPUTED_STATUS (250): - The computed status of the LineItem. - LINE_ITEM_COMPUTED_STATUS_NAME (251): - The localized name of the computed status of - the LineItem. - LINE_ITEM_CONTRACTED_QUANTITY (92): - The contracted units bought for the Line - item. - LINE_ITEM_COST_PER_UNIT (85): - The cost per unit of the Line item. - LINE_ITEM_COST_TYPE (212): - Line item cost type ENUM value. - LINE_ITEM_COST_TYPE_NAME (213): - Localized line item cost type name. - LINE_ITEM_CREATIVE_END_DATE (176): - Represent the end date of a creative - associated with line item - LINE_ITEM_CREATIVE_ROTATION_TYPE (189): - The creative rotation type of the LineItem. - LINE_ITEM_CREATIVE_ROTATION_TYPE_NAME (190): - The localized name of the creative rotation - type of the LineItem. - LINE_ITEM_CREATIVE_START_DATE (175): - Represent the start date of a creative - associated with line item - LINE_ITEM_CURRENCY_CODE (180): - The 3 letter currency code of the Line Item - LINE_ITEM_DELIVERY_INDICATOR (87): - The progress made for the delivery of the - Line item. - LINE_ITEM_DELIVERY_RATE_TYPE (191): - The delivery rate type of the LineItem. - LINE_ITEM_DELIVERY_RATE_TYPE_NAME (192): - The localized name of the delivery rate type - of the LineItem. - LINE_ITEM_DISCOUNT_ABSOLUTE (195): - The discount of the LineItem in whole units - in the LineItem's currency code, or if - unspecified the Network's currency code. - LINE_ITEM_DISCOUNT_PERCENTAGE (196): - The discount of the LineItem in percentage. - LINE_ITEM_END_DATE (81): - The end date of the Line item. - LINE_ITEM_END_DATE_TIME (83): - The end date and time of the Line item. - LINE_ITEM_ENVIRONMENT_TYPE (201): - The ENUM value of the environment a LineItem - is targeting. - LINE_ITEM_ENVIRONMENT_TYPE_NAME (202): - The localized name of the environment a - LineItem is targeting. - LINE_ITEM_EXTERNAL_DEAL_ID (97): - The deal ID of the Line item. Set for - Programmatic Direct campaigns. - LINE_ITEM_EXTERNAL_ID (86): - The external ID of the Line item. - LINE_ITEM_FREQUENCY_CAP (256): - The frequency cap of the Line item - (descriptive string). - LINE_ITEM_ID (1): - Line item ID. - LINE_ITEM_LAST_MODIFIED_BY_APP (181): - The application that last modified the Line - Item. - LINE_ITEM_LIFETIME_CLICKS (95): - The total number of clicks delivered of the - lifetime of the Line item. - LINE_ITEM_LIFETIME_IMPRESSIONS (94): - The total number of impressions delivered - over the lifetime of the Line item. - LINE_ITEM_LIFETIME_VIEWABLE_IMPRESSIONS (96): - The total number of viewable impressions - delivered over the lifetime of the Line item. - LINE_ITEM_MAKEGOOD (89): - Whether or not the Line item is Makegood. - Makegood refers to free inventory offered to - buyers to compensate for mistakes or - under-delivery in the original campaigns. - LINE_ITEM_NAME (2): - Line item Name. - LINE_ITEM_NON_CPD_BOOKED_REVENUE (98): - The cost of booking for the Line item - (non-CPD). - LINE_ITEM_OPTIMIZABLE (90): - Whether a Line item is eligible for - opitimization. - LINE_ITEM_PRIMARY_GOAL_TYPE (210): - Goal type ENUM value of the primary goal of - the line item. - LINE_ITEM_PRIMARY_GOAL_TYPE_NAME (211): - Localized goal type name of the primary goal - of the line item. - LINE_ITEM_PRIMARY_GOAL_UNITS_ABSOLUTE (93): - The total number of impressions or clicks that are reserved - for a line item. For line items of type BULK or - PRICE_PRIORITY, this represents the number of remaining - impressions reserved. If the line item has an impression cap - goal, this represents the number of impressions or - conversions that the line item will stop serving at if - reached. - LINE_ITEM_PRIMARY_GOAL_UNITS_PERCENTAGE (396): - The percentage of impressions or clicks that - are reserved for a line item. For line items of - type SPONSORSHIP, this represents the percentage - of available impressions reserved. For line - items of type NETWORK or HOUSE, this represents - the percentage of remaining impressions - reserved. - LINE_ITEM_PRIMARY_GOAL_UNIT_TYPE (208): - Unit type ENUM value of the primary goal of - the line item. - LINE_ITEM_PRIMARY_GOAL_UNIT_TYPE_NAME (209): - Localized unit type name of the primary goal - of the line item. - LINE_ITEM_PRIORITY (24): - The priority of this Line item as a value - between 1 and 16. In general, a lower priority - means more serving priority for the Line item. - LINE_ITEM_RESERVATION_STATUS (304): - ENUM value describing the state of inventory - reservation for the LineItem. - LINE_ITEM_RESERVATION_STATUS_NAME (305): - Localized string describing the state of - inventory reservation for the LineItem. - LINE_ITEM_START_DATE (82): - The start date of the Line item. - LINE_ITEM_START_DATE_TIME (84): - The start date and time of the Line item. - LINE_ITEM_TYPE (193): - Line item type ENUM value. - LINE_ITEM_TYPE_NAME (194): - Localized line item type name. - LINE_ITEM_UNLIMITED_END (187): - Whether the Line item end time and end date - is set to effectively never end. - LINE_ITEM_VALUE_COST_PER_UNIT (88): - The artificial cost per unit used by the Ad - server to help rank inventory. - LINE_ITEM_WEB_PROPERTY_CODE (179): - The web property code used for dynamic - allocation Line Items. - MASTER_COMPANION_CREATIVE_ID (140): - The ID of creative, includes regular - creatives, and master and companions in case of - creative sets - MASTER_COMPANION_CREATIVE_NAME (141): - Name of creative, includes regular creatives, - and master and companions in case of creative - sets - MOBILE_APP_FREE (128): - Whether the mobile app is free. - MOBILE_APP_ICON_URL (129): - URL of app icon for the mobile app. - MOBILE_APP_ID (123): - The ID of the Mobile App. - MOBILE_APP_NAME (127): - The name of the mobile app. - MOBILE_APP_OWNERSHIP_STATUS (311): - Ownership status of the mobile app. - MOBILE_APP_OWNERSHIP_STATUS_NAME (312): - Ownership status of the mobile app. - MOBILE_APP_STORE (125): - The App Store of the mobile app. - MOBILE_APP_STORE_NAME (245): - The localized name of the mobile app store. - MOBILE_INVENTORY_TYPE (99): - Mobile inventory type. - Identifies whether a mobile ad came from a - regular web page, an AMP web page, or a mobile - app. - Values match the Inventory type dimension - available in the Overview Home dashboard. Note: - Video takes precedence over any other value, for - example, if there is an in-stream video - impression on a desktop device, it will be - attributed to in-stream video and not desktop - web. - MOBILE_INVENTORY_TYPE_NAME (21): - Mobile inventory type name. - Identifies whether a mobile ad came from a - regular web page, an AMP web page, or a mobile - app. - MOBILE_SDK_VERSION_NAME (130): - SDK version of the mobile device. - MONTH_YEAR (6): - Breaks down reporting data by month and year. - NATIVE_AD_FORMAT_ID (255): - Native ad format ID. - NATIVE_AD_FORMAT_NAME (254): - Native ad format name. - NATIVE_STYLE_ID (253): - Native style ID. - NATIVE_STYLE_NAME (252): - Native style name. - OPERATING_SYSTEM_CATEGORY (117): - Operating system category. - OPERATING_SYSTEM_CATEGORY_NAME (118): - Operating system category name. - OPERATING_SYSTEM_VERSION_ID (238): - ID of the operating system version. - OPERATING_SYSTEM_VERSION_NAME (237): - Details of the operating system, including - version. - ORDER_AGENCY (150): - Order agency. - ORDER_AGENCY_ID (151): - Order agency ID. - ORDER_BOOKED_CPC (152): - Order booked CPC. - ORDER_BOOKED_CPM (153): - Order booked CPM. - ORDER_DELIVERY_STATUS (231): - Order delivery status ENUM value. - ORDER_DELIVERY_STATUS_NAME (239): - Order delivery status localized name. - ORDER_END_DATE (154): - Order end date. - ORDER_END_DATE_TIME (155): - Order end date and time. - ORDER_EXTERNAL_ID (156): - Order external ID. - ORDER_ID (7): - Order id. - ORDER_LABELS (170): - Order labels. - ORDER_LABEL_IDS (171): - Order labels IDs. - ORDER_LIFETIME_CLICKS (158): - Order lifetime clicks. - ORDER_LIFETIME_IMPRESSIONS (159): - Order lifetime impressions. - ORDER_NAME (8): - Order name. - ORDER_PO_NUMBER (160): - Order PO number. - ORDER_PROGRAMMATIC (157): - Whether the Order is programmatic. - ORDER_SALESPERSON (161): - Order sales person. - ORDER_SECONDARY_SALESPEOPLE (164): - Order secondary sales people. - ORDER_SECONDARY_SALESPEOPLE_ID (165): - Order secondary sales people ID. - ORDER_SECONDARY_TRAFFICKERS (166): - Order secondary traffickers. - ORDER_SECONDARY_TRAFFICKERS_ID (167): - Order secondary traffickers ID. - ORDER_START_DATE (168): - Order start date. - ORDER_START_DATE_TIME (169): - Order start date and time. - ORDER_TRAFFICKER (162): - Order trafficker. - ORDER_TRAFFICKER_ID (163): - Order trafficker ID. - ORDER_UNLIMITED_END (203): - Whether the Order end time and end date is - set to effectively never end. - PLACEMENT_ID (113): - Placement ID - PLACEMENT_ID_ALL (144): - The full list of placement IDs associated - with the ad unit. - PLACEMENT_NAME (114): - Placement name - PLACEMENT_NAME_ALL (145): - The full list of placement names associated - with the ad unit. - PLACEMENT_STATUS (362): - Placement status ENUM value - PLACEMENT_STATUS_ALL (363): - The full list of placement status ENUM values - associated with the ad unit. - PLACEMENT_STATUS_NAME (364): - Localized placement status name. - PLACEMENT_STATUS_NAME_ALL (365): - The full list of localized placement status - names associated with the ad unit. - PROGRAMMATIC_BUYER_ID (240): - The ID of the buyer on a programmatic - proposal. - PROGRAMMATIC_BUYER_NAME (241): - The name of the buyer on a programmatic - proposal. - PROGRAMMATIC_CHANNEL (13): - Programmatic channel. - The type of transaction that occurred in Ad - Exchange. - PROGRAMMATIC_CHANNEL_NAME (14): - Programmatic channel name. - The type of transaction that occurred in Ad - Exchange. - RENDERED_CREATIVE_SIZE (343): - The size of a rendered creative, It can - differ with the creative's size if a creative is - shown in an ad slot of a different size. - REQUESTED_AD_SIZES (352): - Inventory Requested Ad Sizes dimension - REQUEST_TYPE (146): - Request type ENUM - REQUEST_TYPE_NAME (147): - Request type locallized name - SERVER_SIDE_UNWRAPPING_ELIGIBLE (597): - Indicates if a request was eligible for - server-side unwrapping. - SITE (387): - Information about domain or subdomains. - TARGETING_ID (232): - The ID of the browser, device or other - environment into which a line item or creative - was served. - TARGETING_NAME (233): - Information about the browser, device and - other environments into which a line item or - creative was served. - TARGETING_TYPE (385): - The way in which advertisers targeted their - ads. - TARGETING_TYPE_NAME (386): - The localized name of the way in which - advertisers targeted their ads. - TRAFFIC_SOURCE (388): - Inventory Traffic source dimension - TRAFFIC_SOURCE_NAME (389): - Inventory Traffic source dimension name - UNIFIED_PRICING_RULE_ID (393): - Unified pricing rule ID dimension - UNIFIED_PRICING_RULE_NAME (394): - Unified pricing rule name dimension - VIDEO_PLCMT (172): - The video placement enum as defined by ADCOM - 1.0-202303. - VIDEO_PLCMT_NAME (173): - The localized name of the video placement as - defined by ADCOM 1.0-202303. - WEEK (5): - Breaks down reporting data by week of the - year. - YIELD_GROUP_BUYER_NAME (184): - Name of the company within a yield group - YIELD_GROUP_ID (182): - ID of the group of ad networks or exchanges - used for Mediation and Open Bidding - YIELD_GROUP_NAME (183): - Name of the group of ad networks or exchanges - used for Mediation and Open Bidding - LINE_ITEM_CUSTOM_FIELD_0_OPTION_ID (10000): - Custom field option ID for Line Item with custom field ID - equal to the ID in index 0 of - ``ReportDefinition.line_item_custom_field_ids``. - LINE_ITEM_CUSTOM_FIELD_1_OPTION_ID (10001): - Custom field option ID for Line Item with custom field ID - equal to the ID in index 1 of - ``ReportDefinition.line_item_custom_field_ids``. - LINE_ITEM_CUSTOM_FIELD_2_OPTION_ID (10002): - Custom field option ID for Line Item with custom field ID - equal to the ID in index 2 of - ``ReportDefinition.line_item_custom_field_ids``. - LINE_ITEM_CUSTOM_FIELD_3_OPTION_ID (10003): - Custom field option ID for Line Item with custom field ID - equal to the ID in index 3 of - ``ReportDefinition.line_item_custom_field_ids``. - LINE_ITEM_CUSTOM_FIELD_4_OPTION_ID (10004): - Custom field option ID for Line Item with custom field ID - equal to the ID in index 4 of - ``ReportDefinition.line_item_custom_field_ids``. - LINE_ITEM_CUSTOM_FIELD_5_OPTION_ID (10005): - Custom field option ID for Line Item with custom field ID - equal to the ID in index 5 of - ``ReportDefinition.line_item_custom_field_ids``. - LINE_ITEM_CUSTOM_FIELD_6_OPTION_ID (10006): - Custom field option ID for Line Item with custom field ID - equal to the ID in index 6 of - ``ReportDefinition.line_item_custom_field_ids``. - LINE_ITEM_CUSTOM_FIELD_7_OPTION_ID (10007): - Custom field option ID for Line Item with custom field ID - equal to the ID in index 7 of - ``ReportDefinition.line_item_custom_field_ids``. - LINE_ITEM_CUSTOM_FIELD_8_OPTION_ID (10008): - Custom field option ID for Line Item with custom field ID - equal to the ID in index 8 of - ``ReportDefinition.line_item_custom_field_ids``. - LINE_ITEM_CUSTOM_FIELD_9_OPTION_ID (10009): - Custom field option ID for Line Item with custom field ID - equal to the ID in index 9 of - ``ReportDefinition.line_item_custom_field_ids``. - LINE_ITEM_CUSTOM_FIELD_10_OPTION_ID (10010): - Custom field option ID for Line Item with custom field ID - equal to the ID in index 10 of - ``ReportDefinition.line_item_custom_field_ids``. - LINE_ITEM_CUSTOM_FIELD_11_OPTION_ID (10011): - Custom field option ID for Line Item with custom field ID - equal to the ID in index 11 of - ``ReportDefinition.line_item_custom_field_ids``. - LINE_ITEM_CUSTOM_FIELD_12_OPTION_ID (10012): - Custom field option ID for Line Item with custom field ID - equal to the ID in index 12 of - ``ReportDefinition.line_item_custom_field_ids``. - LINE_ITEM_CUSTOM_FIELD_13_OPTION_ID (10013): - Custom field option ID for Line Item with custom field ID - equal to the ID in index 13 of - ``ReportDefinition.line_item_custom_field_ids``. - LINE_ITEM_CUSTOM_FIELD_14_OPTION_ID (10014): - Custom field option ID for Line Item with custom field ID - equal to the ID in index 14 of - ``ReportDefinition.line_item_custom_field_ids``. - LINE_ITEM_CUSTOM_FIELD_0_VALUE (11000): - Custom field value for Line Item with custom field ID equal - to the ID in index 0 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 0 is of type STRING or DROPDOWN. - LINE_ITEM_CUSTOM_FIELD_1_VALUE (11001): - Custom field value for Line Item with custom field ID equal - to the ID in index 1 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 1 is of type STRING or DROPDOWN. - LINE_ITEM_CUSTOM_FIELD_2_VALUE (11002): - Custom field value for Line Item with custom field ID equal - to the ID in index 2 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 2 is of type STRING or DROPDOWN. - LINE_ITEM_CUSTOM_FIELD_3_VALUE (11003): - Custom field value for Line Item with custom field ID equal - to the ID in index 3 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 3 is of type STRING or DROPDOWN. - LINE_ITEM_CUSTOM_FIELD_4_VALUE (11004): - Custom field value for Line Item with custom field ID equal - to the ID in index 4 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 4 is of type STRING or DROPDOWN. - LINE_ITEM_CUSTOM_FIELD_5_VALUE (11005): - Custom field value for Line Item with custom field ID equal - to the ID in index 5 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 5 is of type STRING or DROPDOWN. - LINE_ITEM_CUSTOM_FIELD_6_VALUE (11006): - Custom field value for Line Item with custom field ID equal - to the ID in index 6 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 6 is of type STRING or DROPDOWN. - LINE_ITEM_CUSTOM_FIELD_7_VALUE (11007): - Custom field value for Line Item with custom field ID equal - to the ID in index 7 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 7 is of type STRING or DROPDOWN. - LINE_ITEM_CUSTOM_FIELD_8_VALUE (11008): - Custom field value for Line Item with custom field ID equal - to the ID in index 8 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 8 is of type STRING or DROPDOWN. - LINE_ITEM_CUSTOM_FIELD_9_VALUE (11009): - Custom field value for Line Item with custom field ID equal - to the ID in index 9 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 9 is of type STRING or DROPDOWN. - LINE_ITEM_CUSTOM_FIELD_10_VALUE (11010): - Custom field value for Line Item with custom field ID equal - to the ID in index 10 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 10 is of type STRING or DROPDOWN. - LINE_ITEM_CUSTOM_FIELD_11_VALUE (11011): - Custom field value for Line Item with custom field ID equal - to the ID in index 11 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 11 is of type STRING or DROPDOWN. - LINE_ITEM_CUSTOM_FIELD_12_VALUE (11012): - Custom field value for Line Item with custom field ID equal - to the ID in index 12 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 12 is of type STRING or DROPDOWN. - LINE_ITEM_CUSTOM_FIELD_13_VALUE (11013): - Custom field value for Line Item with custom field ID equal - to the ID in index 13 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 13 is of type STRING or DROPDOWN. - LINE_ITEM_CUSTOM_FIELD_14_VALUE (11014): - Custom field value for Line Item with custom field ID equal - to the ID in index 14 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 14 is of type STRING or DROPDOWN. - ORDER_CUSTOM_FIELD_0_OPTION_ID (12000): - Custom field option ID for Order with custom field ID equal - to the ID in index 0 of - ``ReportDefinition.order_custom_field_ids``. - ORDER_CUSTOM_FIELD_1_OPTION_ID (12001): - Custom field option ID for Order with custom field ID equal - to the ID in index 1 of - ``ReportDefinition.order_custom_field_ids``. - ORDER_CUSTOM_FIELD_2_OPTION_ID (12002): - Custom field option ID for Order with custom field ID equal - to the ID in index 2 of - ``ReportDefinition.order_custom_field_ids``. - ORDER_CUSTOM_FIELD_3_OPTION_ID (12003): - Custom field option ID for Order with custom field ID equal - to the ID in index 3 of - ``ReportDefinition.order_custom_field_ids``. - ORDER_CUSTOM_FIELD_4_OPTION_ID (12004): - Custom field option ID for Order with custom field ID equal - to the ID in index 4 of - ``ReportDefinition.order_custom_field_ids``. - ORDER_CUSTOM_FIELD_5_OPTION_ID (12005): - Custom field option ID for Order with custom field ID equal - to the ID in index 5 of - ``ReportDefinition.order_custom_field_ids``. - ORDER_CUSTOM_FIELD_6_OPTION_ID (12006): - Custom field option ID for Order with custom field ID equal - to the ID in index 6 of - ``ReportDefinition.order_custom_field_ids``. - ORDER_CUSTOM_FIELD_7_OPTION_ID (12007): - Custom field option ID for Order with custom field ID equal - to the ID in index 7 of - ``ReportDefinition.order_custom_field_ids``. - ORDER_CUSTOM_FIELD_8_OPTION_ID (12008): - Custom field option ID for Order with custom field ID equal - to the ID in index 8 of - ``ReportDefinition.order_custom_field_ids``. - ORDER_CUSTOM_FIELD_9_OPTION_ID (12009): - Custom field option ID for Order with custom field ID equal - to the ID in index 9 of - ``ReportDefinition.order_custom_field_ids``. - ORDER_CUSTOM_FIELD_10_OPTION_ID (12010): - Custom field option ID for Order with custom field ID equal - to the ID in index 10 of - ``ReportDefinition.order_custom_field_ids``. - ORDER_CUSTOM_FIELD_11_OPTION_ID (12011): - Custom field option ID for Order with custom field ID equal - to the ID in index 11 of - ``ReportDefinition.order_custom_field_ids``. - ORDER_CUSTOM_FIELD_12_OPTION_ID (12012): - Custom field option ID for Order with custom field ID equal - to the ID in index 12 of - ``ReportDefinition.order_custom_field_ids``. - ORDER_CUSTOM_FIELD_13_OPTION_ID (12013): - Custom field option ID for Order with custom field ID equal - to the ID in index 13 of - ``ReportDefinition.order_custom_field_ids``. - ORDER_CUSTOM_FIELD_14_OPTION_ID (12014): - Custom field option ID for Order with custom field ID equal - to the ID in index 14 of - ``ReportDefinition.order_custom_field_ids``. - ORDER_CUSTOM_FIELD_0_VALUE (13000): - Custom field value for Order with custom field ID equal to - the ID in index 0 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 0 is of type STRING. - ORDER_CUSTOM_FIELD_1_VALUE (13001): - Custom field value for Order with custom field ID equal to - the ID in index 1 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 1 is of type STRING. - ORDER_CUSTOM_FIELD_2_VALUE (13002): - Custom field value for Order with custom field ID equal to - the ID in index 2 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 2 is of type STRING. - ORDER_CUSTOM_FIELD_3_VALUE (13003): - Custom field value for Order with custom field ID equal to - the ID in index 3 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 3 is of type STRING. - ORDER_CUSTOM_FIELD_4_VALUE (13004): - Custom field value for Order with custom field ID equal to - the ID in index 4 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 4 is of type STRING. - ORDER_CUSTOM_FIELD_5_VALUE (13005): - Custom field value for Order with custom field ID equal to - the ID in index 5 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 5 is of type STRING. - ORDER_CUSTOM_FIELD_6_VALUE (13006): - Custom field value for Order with custom field ID equal to - the ID in index 6 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 6 is of type STRING. - ORDER_CUSTOM_FIELD_7_VALUE (13007): - Custom field value for Order with custom field ID equal to - the ID in index 7 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 7 is of type STRING. - ORDER_CUSTOM_FIELD_8_VALUE (13008): - Custom field value for Order with custom field ID equal to - the ID in index 8 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 8 is of type STRING. - ORDER_CUSTOM_FIELD_9_VALUE (13009): - Custom field value for Order with custom field ID equal to - the ID in index 9 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 9 is of type STRING. - ORDER_CUSTOM_FIELD_10_VALUE (13010): - Custom field value for Order with custom field ID equal to - the ID in index 10 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 10 is of type STRING. - ORDER_CUSTOM_FIELD_11_VALUE (13011): - Custom field value for Order with custom field ID equal to - the ID in index 11 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 11 is of type STRING. - ORDER_CUSTOM_FIELD_12_VALUE (13012): - Custom field value for Order with custom field ID equal to - the ID in index 12 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 12 is of type STRING. - ORDER_CUSTOM_FIELD_13_VALUE (13013): - Custom field value for Order with custom field ID equal to - the ID in index 13 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 13 is of type STRING. - ORDER_CUSTOM_FIELD_14_VALUE (13014): - Custom field value for Order with custom field ID equal to - the ID in index 14 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 14 is of type STRING. - CREATIVE_CUSTOM_FIELD_0_OPTION_ID (14000): - Custom field option ID for Creative with custom field ID - equal to the ID in index 0 of - ``ReportDefinition.creative_custom_field_ids``. - CREATIVE_CUSTOM_FIELD_1_OPTION_ID (14001): - Custom field option ID for Creative with custom field ID - equal to the ID in index 1 of - ``ReportDefinition.creative_custom_field_ids``. - CREATIVE_CUSTOM_FIELD_2_OPTION_ID (14002): - Custom field option ID for Creative with custom field ID - equal to the ID in index 2 of - ``ReportDefinition.creative_custom_field_ids``. - CREATIVE_CUSTOM_FIELD_3_OPTION_ID (14003): - Custom field option ID for Creative with custom field ID - equal to the ID in index 3 of - ``ReportDefinition.creative_custom_field_ids``. - CREATIVE_CUSTOM_FIELD_4_OPTION_ID (14004): - Custom field option ID for Creative with custom field ID - equal to the ID in index 4 of - ``ReportDefinition.creative_custom_field_ids``. - CREATIVE_CUSTOM_FIELD_5_OPTION_ID (14005): - Custom field option ID for Creative with custom field ID - equal to the ID in index 5 of - ``ReportDefinition.creative_custom_field_ids``. - CREATIVE_CUSTOM_FIELD_6_OPTION_ID (14006): - Custom field option ID for Creative with custom field ID - equal to the ID in index 6 of - ``ReportDefinition.creative_custom_field_ids``. - CREATIVE_CUSTOM_FIELD_7_OPTION_ID (14007): - Custom field option ID for Creative with custom field ID - equal to the ID in index 7 of - ``ReportDefinition.creative_custom_field_ids``. - CREATIVE_CUSTOM_FIELD_8_OPTION_ID (14008): - Custom field option ID for Creative with custom field ID - equal to the ID in index 8 of - ``ReportDefinition.creative_custom_field_ids``. - CREATIVE_CUSTOM_FIELD_9_OPTION_ID (14009): - Custom field option ID for Creative with custom field ID - equal to the ID in index 9 of - ``ReportDefinition.creative_custom_field_ids``. - CREATIVE_CUSTOM_FIELD_10_OPTION_ID (14010): - Custom field option ID for Creative with custom field ID - equal to the ID in index 10 of - ``ReportDefinition.creative_custom_field_ids``. - CREATIVE_CUSTOM_FIELD_11_OPTION_ID (14011): - Custom field option ID for Creative with custom field ID - equal to the ID in index 11 of - ``ReportDefinition.creative_custom_field_ids``. - CREATIVE_CUSTOM_FIELD_12_OPTION_ID (14012): - Custom field option ID for Creative with custom field ID - equal to the ID in index 12 of - ``ReportDefinition.creative_custom_field_ids``. - CREATIVE_CUSTOM_FIELD_13_OPTION_ID (14013): - Custom field option ID for Creative with custom field ID - equal to the ID in index 13 of - ``ReportDefinition.creative_custom_field_ids``. - CREATIVE_CUSTOM_FIELD_14_OPTION_ID (14014): - Custom field option ID for Creative with custom field ID - equal to the ID in index 14 of - ``ReportDefinition.creative_custom_field_ids``. - CREATIVE_CUSTOM_FIELD_0_VALUE (15000): - Custom field value for Creative with custom field ID equal - to the ID in index 0 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 0 is of type STRING. - CREATIVE_CUSTOM_FIELD_1_VALUE (15001): - Custom field value for Creative with custom field ID equal - to the ID in index 1 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 1 is of type STRING. - CREATIVE_CUSTOM_FIELD_2_VALUE (15002): - Custom field value for Creative with custom field ID equal - to the ID in index 2 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 2 is of type STRING. - CREATIVE_CUSTOM_FIELD_3_VALUE (15003): - Custom field value for Creative with custom field ID equal - to the ID in index 3 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 3 is of type STRING. - CREATIVE_CUSTOM_FIELD_4_VALUE (15004): - Custom field value for Creative with custom field ID equal - to the ID in index 4 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 4 is of type STRING. - CREATIVE_CUSTOM_FIELD_5_VALUE (15005): - Custom field value for Creative with custom field ID equal - to the ID in index 5 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 5 is of type STRING. - CREATIVE_CUSTOM_FIELD_6_VALUE (15006): - Custom field value for Creative with custom field ID equal - to the ID in index 6 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 6 is of type STRING. - CREATIVE_CUSTOM_FIELD_7_VALUE (15007): - Custom field value for Creative with custom field ID equal - to the ID in index 7 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 7 is of type STRING. - CREATIVE_CUSTOM_FIELD_8_VALUE (15008): - Custom field value for Creative with custom field ID equal - to the ID in index 8 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 8 is of type STRING. - CREATIVE_CUSTOM_FIELD_9_VALUE (15009): - Custom field value for Creative with custom field ID equal - to the ID in index 9 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 9 is of type STRING. - CREATIVE_CUSTOM_FIELD_10_VALUE (15010): - Custom field value for Creative with custom field ID equal - to the ID in index 10 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 10 is of type STRING. - CREATIVE_CUSTOM_FIELD_11_VALUE (15011): - Custom field value for Creative with custom field ID equal - to the ID in index 11 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 11 is of type STRING. - CREATIVE_CUSTOM_FIELD_12_VALUE (15012): - Custom field value for Creative with custom field ID equal - to the ID in index 12 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 12 is of type STRING. - CREATIVE_CUSTOM_FIELD_13_VALUE (15013): - Custom field value for Creative with custom field ID equal - to the ID in index 13 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 13 is of type STRING. - CREATIVE_CUSTOM_FIELD_14_VALUE (15014): - Custom field value for Creative with custom field ID equal - to the ID in index 14 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 14 is of type STRING. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_0_OPTION_ID (16000): - Custom field option ID for Backfill line item with custom - field ID equal to the ID in index 0 of - ``ReportDefinition.line_item_custom_field_ids``. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_1_OPTION_ID (16001): - Custom field option ID for Backfill line item with custom - field ID equal to the ID in index 1 of - ``ReportDefinition.line_item_custom_field_ids``. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_2_OPTION_ID (16002): - Custom field option ID for Backfill line item with custom - field ID equal to the ID in index 2 of - ``ReportDefinition.line_item_custom_field_ids``. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_3_OPTION_ID (16003): - Custom field option ID for Backfill line item with custom - field ID equal to the ID in index 3 of - ``ReportDefinition.line_item_custom_field_ids``. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_4_OPTION_ID (16004): - Custom field option ID for Backfill line item with custom - field ID equal to the ID in index 4 of - ``ReportDefinition.line_item_custom_field_ids``. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_5_OPTION_ID (16005): - Custom field option ID for Backfill line item with custom - field ID equal to the ID in index 5 of - ``ReportDefinition.line_item_custom_field_ids``. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_6_OPTION_ID (16006): - Custom field option ID for Backfill line item with custom - field ID equal to the ID in index 6 of - ``ReportDefinition.line_item_custom_field_ids``. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_7_OPTION_ID (16007): - Custom field option ID for Backfill line item with custom - field ID equal to the ID in index 7 of - ``ReportDefinition.line_item_custom_field_ids``. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_8_OPTION_ID (16008): - Custom field option ID for Backfill line item with custom - field ID equal to the ID in index 8 of - ``ReportDefinition.line_item_custom_field_ids``. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_9_OPTION_ID (16009): - Custom field option ID for Backfill line item with custom - field ID equal to the ID in index 9 of - ``ReportDefinition.line_item_custom_field_ids``. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_10_OPTION_ID (16010): - Custom field option ID for Backfill line item with custom - field ID equal to the ID in index 10 of - ``ReportDefinition.line_item_custom_field_ids``. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_11_OPTION_ID (16011): - Custom field option ID for Backfill line item with custom - field ID equal to the ID in index 11 of - ``ReportDefinition.line_item_custom_field_ids``. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_12_OPTION_ID (16012): - Custom field option ID for Backfill line item with custom - field ID equal to the ID in index 12 of - ``ReportDefinition.line_item_custom_field_ids``. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_13_OPTION_ID (16013): - Custom field option ID for Backfill line item with custom - field ID equal to the ID in index 13 of - ``ReportDefinition.line_item_custom_field_ids``. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_14_OPTION_ID (16014): - Custom field option ID for Backfill line item with custom - field ID equal to the ID in index 14 of - ``ReportDefinition.line_item_custom_field_ids``. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_0_VALUE (17000): - Custom field value for Backfill line item with custom field - ID equal to the ID in index 0 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 0 is of type STRING or DROPDOWN. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_1_VALUE (17001): - Custom field value for Backfill line item with custom field - ID equal to the ID in index 1 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 1 is of type STRING or DROPDOWN. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_2_VALUE (17002): - Custom field value for Backfill line item with custom field - ID equal to the ID in index 2 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 2 is of type STRING or DROPDOWN. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_3_VALUE (17003): - Custom field value for Backfill line item with custom field - ID equal to the ID in index 3 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 3 is of type STRING or DROPDOWN. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_4_VALUE (17004): - Custom field value for Backfill line item with custom field - ID equal to the ID in index 4 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 4 is of type STRING or DROPDOWN. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_5_VALUE (17005): - Custom field value for Backfill line item with custom field - ID equal to the ID in index 5 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 5 is of type STRING or DROPDOWN. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_6_VALUE (17006): - Custom field value for Backfill line item with custom field - ID equal to the ID in index 6 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 6 is of type STRING or DROPDOWN. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_7_VALUE (17007): - Custom field value for Backfill line item with custom field - ID equal to the ID in index 7 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 7 is of type STRING or DROPDOWN. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_8_VALUE (17008): - Custom field value for Backfill line item with custom field - ID equal to the ID in index 8 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 8 is of type STRING or DROPDOWN. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_9_VALUE (17009): - Custom field value for Backfill line item with custom field - ID equal to the ID in index 9 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 9 is of type STRING or DROPDOWN. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_10_VALUE (17010): - Custom field value for Backfill line item with custom field - ID equal to the ID in index 10 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 10 is of type STRING or DROPDOWN. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_11_VALUE (17011): - Custom field value for Backfill line item with custom field - ID equal to the ID in index 11 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 11 is of type STRING or DROPDOWN. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_12_VALUE (17012): - Custom field value for Backfill line item with custom field - ID equal to the ID in index 12 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 12 is of type STRING or DROPDOWN. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_13_VALUE (17013): - Custom field value for Backfill line item with custom field - ID equal to the ID in index 13 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 13 is of type STRING or DROPDOWN. - BACKFILL_LINE_ITEM_CUSTOM_FIELD_14_VALUE (17014): - Custom field value for Backfill line item with custom field - ID equal to the ID in index 14 of - ``ReportDefinition.line_item_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 14 is of type STRING or DROPDOWN. - BACKFILL_ORDER_CUSTOM_FIELD_0_OPTION_ID (18000): - Custom field option ID for Backfill order with custom field - ID equal to the ID in index 0 of - ``ReportDefinition.order_custom_field_ids``. - BACKFILL_ORDER_CUSTOM_FIELD_1_OPTION_ID (18001): - Custom field option ID for Backfill order with custom field - ID equal to the ID in index 1 of - ``ReportDefinition.order_custom_field_ids``. - BACKFILL_ORDER_CUSTOM_FIELD_2_OPTION_ID (18002): - Custom field option ID for Backfill order with custom field - ID equal to the ID in index 2 of - ``ReportDefinition.order_custom_field_ids``. - BACKFILL_ORDER_CUSTOM_FIELD_3_OPTION_ID (18003): - Custom field option ID for Backfill order with custom field - ID equal to the ID in index 3 of - ``ReportDefinition.order_custom_field_ids``. - BACKFILL_ORDER_CUSTOM_FIELD_4_OPTION_ID (18004): - Custom field option ID for Backfill order with custom field - ID equal to the ID in index 4 of - ``ReportDefinition.order_custom_field_ids``. - BACKFILL_ORDER_CUSTOM_FIELD_5_OPTION_ID (18005): - Custom field option ID for Backfill order with custom field - ID equal to the ID in index 5 of - ``ReportDefinition.order_custom_field_ids``. - BACKFILL_ORDER_CUSTOM_FIELD_6_OPTION_ID (18006): - Custom field option ID for Backfill order with custom field - ID equal to the ID in index 6 of - ``ReportDefinition.order_custom_field_ids``. - BACKFILL_ORDER_CUSTOM_FIELD_7_OPTION_ID (18007): - Custom field option ID for Backfill order with custom field - ID equal to the ID in index 7 of - ``ReportDefinition.order_custom_field_ids``. - BACKFILL_ORDER_CUSTOM_FIELD_8_OPTION_ID (18008): - Custom field option ID for Backfill order with custom field - ID equal to the ID in index 8 of - ``ReportDefinition.order_custom_field_ids``. - BACKFILL_ORDER_CUSTOM_FIELD_9_OPTION_ID (18009): - Custom field option ID for Backfill order with custom field - ID equal to the ID in index 9 of - ``ReportDefinition.order_custom_field_ids``. - BACKFILL_ORDER_CUSTOM_FIELD_10_OPTION_ID (18010): - Custom field option ID for Backfill order with custom field - ID equal to the ID in index 10 of - ``ReportDefinition.order_custom_field_ids``. - BACKFILL_ORDER_CUSTOM_FIELD_11_OPTION_ID (18011): - Custom field option ID for Backfill order with custom field - ID equal to the ID in index 11 of - ``ReportDefinition.order_custom_field_ids``. - BACKFILL_ORDER_CUSTOM_FIELD_12_OPTION_ID (18012): - Custom field option ID for Backfill order with custom field - ID equal to the ID in index 12 of - ``ReportDefinition.order_custom_field_ids``. - BACKFILL_ORDER_CUSTOM_FIELD_13_OPTION_ID (18013): - Custom field option ID for Backfill order with custom field - ID equal to the ID in index 13 of - ``ReportDefinition.order_custom_field_ids``. - BACKFILL_ORDER_CUSTOM_FIELD_14_OPTION_ID (18014): - Custom field option ID for Backfill order with custom field - ID equal to the ID in index 14 of - ``ReportDefinition.order_custom_field_ids``. - BACKFILL_ORDER_CUSTOM_FIELD_0_VALUE (19000): - Custom field value for Backfill order with custom field ID - equal to the ID in index 0 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 0 is of type STRING or DROPDOWN. - BACKFILL_ORDER_CUSTOM_FIELD_1_VALUE (19001): - Custom field value for Backfill order with custom field ID - equal to the ID in index 1 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 1 is of type STRING or DROPDOWN. - BACKFILL_ORDER_CUSTOM_FIELD_2_VALUE (19002): - Custom field value for Backfill order with custom field ID - equal to the ID in index 2 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 2 is of type STRING or DROPDOWN. - BACKFILL_ORDER_CUSTOM_FIELD_3_VALUE (19003): - Custom field value for Backfill order with custom field ID - equal to the ID in index 3 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 3 is of type STRING or DROPDOWN. - BACKFILL_ORDER_CUSTOM_FIELD_4_VALUE (19004): - Custom field value for Backfill order with custom field ID - equal to the ID in index 4 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 4 is of type STRING or DROPDOWN. - BACKFILL_ORDER_CUSTOM_FIELD_5_VALUE (19005): - Custom field value for Backfill order with custom field ID - equal to the ID in index 5 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 5 is of type STRING or DROPDOWN. - BACKFILL_ORDER_CUSTOM_FIELD_6_VALUE (19006): - Custom field value for Backfill order with custom field ID - equal to the ID in index 6 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 6 is of type STRING or DROPDOWN. - BACKFILL_ORDER_CUSTOM_FIELD_7_VALUE (19007): - Custom field value for Backfill order with custom field ID - equal to the ID in index 7 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 7 is of type STRING or DROPDOWN. - BACKFILL_ORDER_CUSTOM_FIELD_8_VALUE (19008): - Custom field value for Backfill order with custom field ID - equal to the ID in index 8 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 8 is of type STRING or DROPDOWN. - BACKFILL_ORDER_CUSTOM_FIELD_9_VALUE (19009): - Custom field value for Backfill order with custom field ID - equal to the ID in index 9 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 9 is of type STRING or DROPDOWN. - BACKFILL_ORDER_CUSTOM_FIELD_10_VALUE (19010): - Custom field value for Backfill order with custom field ID - equal to the ID in index 10 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 10 is of type STRING or DROPDOWN. - BACKFILL_ORDER_CUSTOM_FIELD_11_VALUE (19011): - Custom field value for Backfill order with custom field ID - equal to the ID in index 11 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 11 is of type STRING or DROPDOWN. - BACKFILL_ORDER_CUSTOM_FIELD_12_VALUE (19012): - Custom field value for Backfill order with custom field ID - equal to the ID in index 12 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 12 is of type STRING or DROPDOWN. - BACKFILL_ORDER_CUSTOM_FIELD_13_VALUE (19013): - Custom field value for Backfill order with custom field ID - equal to the ID in index 13 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 13 is of type STRING or DROPDOWN. - BACKFILL_ORDER_CUSTOM_FIELD_14_VALUE (19014): - Custom field value for Backfill order with custom field ID - equal to the ID in index 14 of - ``ReportDefinition.order_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 14 is of type STRING or DROPDOWN. - BACKFILL_CREATIVE_CUSTOM_FIELD_0_OPTION_ID (20000): - Custom field option ID for Backfill creative with custom - field ID equal to the ID in index 0 of - ``ReportDefinition.creative_custom_field_ids``. - BACKFILL_CREATIVE_CUSTOM_FIELD_1_OPTION_ID (20001): - Custom field option ID for Backfill creative with custom - field ID equal to the ID in index 1 of - ``ReportDefinition.creative_custom_field_ids``. - BACKFILL_CREATIVE_CUSTOM_FIELD_2_OPTION_ID (20002): - Custom field option ID for Backfill creative with custom - field ID equal to the ID in index 2 of - ``ReportDefinition.creative_custom_field_ids``. - BACKFILL_CREATIVE_CUSTOM_FIELD_3_OPTION_ID (20003): - Custom field option ID for Backfill creative with custom - field ID equal to the ID in index 3 of - ``ReportDefinition.creative_custom_field_ids``. - BACKFILL_CREATIVE_CUSTOM_FIELD_4_OPTION_ID (20004): - Custom field option ID for Backfill creative with custom - field ID equal to the ID in index 4 of - ``ReportDefinition.creative_custom_field_ids``. - BACKFILL_CREATIVE_CUSTOM_FIELD_5_OPTION_ID (20005): - Custom field option ID for Backfill creative with custom - field ID equal to the ID in index 5 of - ``ReportDefinition.creative_custom_field_ids``. - BACKFILL_CREATIVE_CUSTOM_FIELD_6_OPTION_ID (20006): - Custom field option ID for Backfill creative with custom - field ID equal to the ID in index 6 of - ``ReportDefinition.creative_custom_field_ids``. - BACKFILL_CREATIVE_CUSTOM_FIELD_7_OPTION_ID (20007): - Custom field option ID for Backfill creative with custom - field ID equal to the ID in index 7 of - ``ReportDefinition.creative_custom_field_ids``. - BACKFILL_CREATIVE_CUSTOM_FIELD_8_OPTION_ID (20008): - Custom field option ID for Backfill creative with custom - field ID equal to the ID in index 8 of - ``ReportDefinition.creative_custom_field_ids``. - BACKFILL_CREATIVE_CUSTOM_FIELD_9_OPTION_ID (20009): - Custom field option ID for Backfill creative with custom - field ID equal to the ID in index 9 of - ``ReportDefinition.creative_custom_field_ids``. - BACKFILL_CREATIVE_CUSTOM_FIELD_10_OPTION_ID (20010): - Custom field option ID for Backfill creative with custom - field ID equal to the ID in index 10 of - ``ReportDefinition.creative_custom_field_ids``. - BACKFILL_CREATIVE_CUSTOM_FIELD_11_OPTION_ID (20011): - Custom field option ID for Backfill creative with custom - field ID equal to the ID in index 11 of - ``ReportDefinition.creative_custom_field_ids``. - BACKFILL_CREATIVE_CUSTOM_FIELD_12_OPTION_ID (20012): - Custom field option ID for Backfill creative with custom - field ID equal to the ID in index 12 of - ``ReportDefinition.creative_custom_field_ids``. - BACKFILL_CREATIVE_CUSTOM_FIELD_13_OPTION_ID (20013): - Custom field option ID for Backfill creative with custom - field ID equal to the ID in index 13 of - ``ReportDefinition.creative_custom_field_ids``. - BACKFILL_CREATIVE_CUSTOM_FIELD_14_OPTION_ID (20014): - Custom field option ID for Backfill creative with custom - field ID equal to the ID in index 14 of - ``ReportDefinition.creative_custom_field_ids``. - BACKFILL_CREATIVE_CUSTOM_FIELD_0_VALUE (21000): - Custom field value for Backfill creative with custom field - ID equal to the ID in index 0 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 0 is of type STRING or DROPDOWN. - BACKFILL_CREATIVE_CUSTOM_FIELD_1_VALUE (21001): - Custom field value for Backfill creative with custom field - ID equal to the ID in index 1 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 1 is of type STRING or DROPDOWN. - BACKFILL_CREATIVE_CUSTOM_FIELD_2_VALUE (21002): - Custom field value for Backfill creative with custom field - ID equal to the ID in index 2 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 2 is of type STRING or DROPDOWN. - BACKFILL_CREATIVE_CUSTOM_FIELD_3_VALUE (21003): - Custom field value for Backfill creative with custom field - ID equal to the ID in index 3 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 3 is of type STRING or DROPDOWN. - BACKFILL_CREATIVE_CUSTOM_FIELD_4_VALUE (21004): - Custom field value for Backfill creative with custom field - ID equal to the ID in index 4 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 4 is of type STRING or DROPDOWN. - BACKFILL_CREATIVE_CUSTOM_FIELD_5_VALUE (21005): - Custom field value for Backfill creative with custom field - ID equal to the ID in index 5 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 5 is of type STRING or DROPDOWN. - BACKFILL_CREATIVE_CUSTOM_FIELD_6_VALUE (21006): - Custom field value for Backfill creative with custom field - ID equal to the ID in index 6 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 6 is of type STRING or DROPDOWN. - BACKFILL_CREATIVE_CUSTOM_FIELD_7_VALUE (21007): - Custom field value for Backfill creative with custom field - ID equal to the ID in index 7 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 7 is of type STRING or DROPDOWN. - BACKFILL_CREATIVE_CUSTOM_FIELD_8_VALUE (21008): - Custom field value for Backfill creative with custom field - ID equal to the ID in index 8 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 8 is of type STRING or DROPDOWN. - BACKFILL_CREATIVE_CUSTOM_FIELD_9_VALUE (21009): - Custom field value for Backfill creative with custom field - ID equal to the ID in index 9 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 9 is of type STRING or DROPDOWN. - BACKFILL_CREATIVE_CUSTOM_FIELD_10_VALUE (21010): - Custom field value for Backfill creative with custom field - ID equal to the ID in index 10 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 10 is of type STRING or DROPDOWN. - BACKFILL_CREATIVE_CUSTOM_FIELD_11_VALUE (21011): - Custom field value for Backfill creative with custom field - ID equal to the ID in index 11 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 11 is of type STRING or DROPDOWN. - BACKFILL_CREATIVE_CUSTOM_FIELD_12_VALUE (21012): - Custom field value for Backfill creative with custom field - ID equal to the ID in index 12 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 12 is of type STRING or DROPDOWN. - BACKFILL_CREATIVE_CUSTOM_FIELD_13_VALUE (21013): - Custom field value for Backfill creative with custom field - ID equal to the ID in index 13 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 13 is of type STRING or DROPDOWN. - BACKFILL_CREATIVE_CUSTOM_FIELD_14_VALUE (21014): - Custom field value for Backfill creative with custom field - ID equal to the ID in index 14 of - ``ReportDefinition.creative_custom_field_ids``. Treats the - value as a string. Can only be used if the custom field at - index 14 is of type STRING or DROPDOWN. - CUSTOM_DIMENSION_0_VALUE_ID (100000): - Custom Dimension Value ID for Custom Dimension with key - equal to the key in index 0 of - ``ReportDefinition.custom_dimension_key_ids``. - CUSTOM_DIMENSION_1_VALUE_ID (100001): - Custom Dimension Value ID for Custom Dimension with key - equal to the key in index 1 of - ``ReportDefinition.custom_dimension_key_ids``. - CUSTOM_DIMENSION_2_VALUE_ID (100002): - Custom Dimension Value ID for Custom Dimension with key - equal to the key in index 2 of - ``ReportDefinition.custom_dimension_key_ids``. - CUSTOM_DIMENSION_3_VALUE_ID (100003): - Custom Dimension Value ID for Custom Dimension with key - equal to the key in index 3 of - ``ReportDefinition.custom_dimension_key_ids``. - CUSTOM_DIMENSION_4_VALUE_ID (100004): - Custom Dimension Value ID for Custom Dimension with key - equal to the key in index 4 of - ``ReportDefinition.custom_dimension_key_ids``. - CUSTOM_DIMENSION_5_VALUE_ID (100005): - Custom Dimension Value ID for Custom Dimension with key - equal to the key in index 5 of - ``ReportDefinition.custom_dimension_key_ids``. - CUSTOM_DIMENSION_6_VALUE_ID (100006): - Custom Dimension Value ID for Custom Dimension with key - equal to the key in index 6 of - ``ReportDefinition.custom_dimension_key_ids``. - CUSTOM_DIMENSION_7_VALUE_ID (100007): - Custom Dimension Value ID for Custom Dimension with key - equal to the key in index 9 of - ``ReportDefinition.custom_dimension_key_ids``. - CUSTOM_DIMENSION_8_VALUE_ID (100008): - Custom Dimension Value ID for Custom Dimension with key - equal to the key in index 8 of - ``ReportDefinition.custom_dimension_key_ids``. - CUSTOM_DIMENSION_9_VALUE_ID (100009): - Custom Dimension Value ID for Custom Dimension with key - equal to the key in index 9 of - ``ReportDefinition.custom_dimension_key_ids``. - CUSTOM_DIMENSION_0_VALUE (101000): - Custom Dimension Value name for Custom Dimension with key - equal to the id in index 0 of - ``ReportDefinition.custom_dimension_key_ids``. - CUSTOM_DIMENSION_1_VALUE (101001): - Custom Dimension Value name for Custom Dimension with key - equal to the id in index 1 of - ``ReportDefinition.custom_dimension_key_ids``. - CUSTOM_DIMENSION_2_VALUE (101002): - Custom Dimension Value name for Custom Dimension with key - equal to the id in index 2 of - ``ReportDefinition.custom_dimension_key_ids``. - CUSTOM_DIMENSION_3_VALUE (101003): - Custom Dimension Value name for Custom Dimension with key - equal to the id in index 3 of - ``ReportDefinition.custom_dimension_key_ids``. - CUSTOM_DIMENSION_4_VALUE (101004): - Custom Dimension Value name for Custom Dimension with key - equal to the id in index 4 of - ``ReportDefinition.custom_dimension_key_ids``. - CUSTOM_DIMENSION_5_VALUE (101005): - Custom Dimension Value name for Custom Dimension with key - equal to the id in index 5 of - ``ReportDefinition.custom_dimension_key_ids``. - CUSTOM_DIMENSION_6_VALUE (101006): - Custom Dimension Value name for Custom Dimension with key - equal to the id in index 6 of - ``ReportDefinition.custom_dimension_key_ids``. - CUSTOM_DIMENSION_7_VALUE (101007): - Custom Dimension Value name for Custom Dimension with key - equal to the id in index 7 of - ``ReportDefinition.custom_dimension_key_ids``. - CUSTOM_DIMENSION_8_VALUE (101008): - Custom Dimension Value name for Custom Dimension with key - equal to the id in index 8 of - ``ReportDefinition.custom_dimension_key_ids``. - CUSTOM_DIMENSION_9_VALUE (101009): - Custom Dimension Value name for Custom Dimension with key - equal to the id in index 9 of - ``ReportDefinition.custom_dimension_key_ids``. - """ - DIMENSION_UNSPECIFIED = 0 - ADVERTISER_DOMAIN_NAME = 242 - ADVERTISER_EXTERNAL_ID = 228 - ADVERTISER_ID = 131 - ADVERTISER_LABELS = 230 - ADVERTISER_LABEL_IDS = 229 - ADVERTISER_NAME = 132 - ADVERTISER_PRIMARY_CONTACT = 227 - AD_LOCATION = 390 - AD_LOCATION_NAME = 391 - AD_UNIT_CODE = 64 - AD_UNIT_CODE_LEVEL_1 = 65 - AD_UNIT_CODE_LEVEL_10 = 74 - AD_UNIT_CODE_LEVEL_11 = 75 - AD_UNIT_CODE_LEVEL_12 = 76 - AD_UNIT_CODE_LEVEL_13 = 77 - AD_UNIT_CODE_LEVEL_14 = 78 - AD_UNIT_CODE_LEVEL_15 = 79 - AD_UNIT_CODE_LEVEL_16 = 80 - AD_UNIT_CODE_LEVEL_2 = 66 - AD_UNIT_CODE_LEVEL_3 = 67 - AD_UNIT_CODE_LEVEL_4 = 68 - AD_UNIT_CODE_LEVEL_5 = 69 - AD_UNIT_CODE_LEVEL_6 = 70 - AD_UNIT_CODE_LEVEL_7 = 71 - AD_UNIT_CODE_LEVEL_8 = 72 - AD_UNIT_CODE_LEVEL_9 = 73 - AD_UNIT_DEPTH = 101 - AD_UNIT_ID = 25 - AD_UNIT_ID_ALL_LEVEL = 27 - AD_UNIT_ID_LEVEL_1 = 30 - AD_UNIT_ID_LEVEL_10 = 48 - AD_UNIT_ID_LEVEL_11 = 50 - AD_UNIT_ID_LEVEL_12 = 52 - AD_UNIT_ID_LEVEL_13 = 54 - AD_UNIT_ID_LEVEL_14 = 56 - AD_UNIT_ID_LEVEL_15 = 58 - AD_UNIT_ID_LEVEL_16 = 60 - AD_UNIT_ID_LEVEL_2 = 32 - AD_UNIT_ID_LEVEL_3 = 34 - AD_UNIT_ID_LEVEL_4 = 36 - AD_UNIT_ID_LEVEL_5 = 38 - AD_UNIT_ID_LEVEL_6 = 40 - AD_UNIT_ID_LEVEL_7 = 42 - AD_UNIT_ID_LEVEL_8 = 44 - AD_UNIT_ID_LEVEL_9 = 46 - AD_UNIT_ID_TOP_LEVEL = 142 - AD_UNIT_NAME = 26 - AD_UNIT_NAME_ALL_LEVEL = 29 - AD_UNIT_NAME_LEVEL_1 = 31 - AD_UNIT_NAME_LEVEL_10 = 49 - AD_UNIT_NAME_LEVEL_11 = 51 - AD_UNIT_NAME_LEVEL_12 = 53 - AD_UNIT_NAME_LEVEL_13 = 55 - AD_UNIT_NAME_LEVEL_14 = 57 - AD_UNIT_NAME_LEVEL_15 = 59 - AD_UNIT_NAME_LEVEL_16 = 61 - AD_UNIT_NAME_LEVEL_2 = 33 - AD_UNIT_NAME_LEVEL_3 = 35 - AD_UNIT_NAME_LEVEL_4 = 37 - AD_UNIT_NAME_LEVEL_5 = 39 - AD_UNIT_NAME_LEVEL_6 = 41 - AD_UNIT_NAME_LEVEL_7 = 43 - AD_UNIT_NAME_LEVEL_8 = 45 - AD_UNIT_NAME_LEVEL_9 = 47 - AD_UNIT_NAME_TOP_LEVEL = 143 - AD_UNIT_REWARD_AMOUNT = 63 - AD_UNIT_REWARD_TYPE = 62 - AD_UNIT_STATUS = 206 - AD_UNIT_STATUS_NAME = 207 - APP_VERSION = 392 - BACKFILL_ADVERTISER_EXTERNAL_ID = 349 - BACKFILL_ADVERTISER_ID = 346 - BACKFILL_ADVERTISER_LABELS = 351 - BACKFILL_ADVERTISER_LABEL_IDS = 350 - BACKFILL_ADVERTISER_NAME = 347 - BACKFILL_ADVERTISER_PRIMARY_CONTACT = 348 - BACKFILL_CREATIVE_BILLING_TYPE = 378 - BACKFILL_CREATIVE_BILLING_TYPE_NAME = 379 - BACKFILL_CREATIVE_CLICK_THROUGH_URL = 376 - BACKFILL_CREATIVE_ID = 370 - BACKFILL_CREATIVE_NAME = 371 - BACKFILL_CREATIVE_THIRD_PARTY_VENDOR = 377 - BACKFILL_CREATIVE_TYPE = 374 - BACKFILL_CREATIVE_TYPE_NAME = 375 - BACKFILL_LINE_ITEM_ARCHIVED = 278 - BACKFILL_LINE_ITEM_COMPANION_DELIVERY_OPTION = 258 - BACKFILL_LINE_ITEM_COMPANION_DELIVERY_OPTION_NAME = 259 - BACKFILL_LINE_ITEM_COMPUTED_STATUS = 296 - BACKFILL_LINE_ITEM_COMPUTED_STATUS_NAME = 297 - BACKFILL_LINE_ITEM_CONTRACTED_QUANTITY = 280 - BACKFILL_LINE_ITEM_COST_PER_UNIT = 272 - BACKFILL_LINE_ITEM_COST_TYPE = 264 - BACKFILL_LINE_ITEM_COST_TYPE_NAME = 265 - BACKFILL_LINE_ITEM_CREATIVE_END_DATE = 381 - BACKFILL_LINE_ITEM_CREATIVE_ROTATION_TYPE = 290 - BACKFILL_LINE_ITEM_CREATIVE_ROTATION_TYPE_NAME = 291 - BACKFILL_LINE_ITEM_CREATIVE_START_DATE = 380 - BACKFILL_LINE_ITEM_CURRENCY_CODE = 288 - BACKFILL_LINE_ITEM_DELIVERY_INDICATOR = 274 - BACKFILL_LINE_ITEM_DELIVERY_RATE_TYPE = 292 - BACKFILL_LINE_ITEM_DELIVERY_RATE_TYPE_NAME = 293 - BACKFILL_LINE_ITEM_DISCOUNT_ABSOLUTE = 294 - BACKFILL_LINE_ITEM_DISCOUNT_PERCENTAGE = 295 - BACKFILL_LINE_ITEM_END_DATE = 267 - BACKFILL_LINE_ITEM_END_DATE_TIME = 269 - BACKFILL_LINE_ITEM_ENVIRONMENT_TYPE = 302 - BACKFILL_LINE_ITEM_ENVIRONMENT_TYPE_NAME = 257 - BACKFILL_LINE_ITEM_EXTERNAL_DEAL_ID = 285 - BACKFILL_LINE_ITEM_EXTERNAL_ID = 273 - BACKFILL_LINE_ITEM_FREQUENCY_CAP = 303 - BACKFILL_LINE_ITEM_ID = 298 - BACKFILL_LINE_ITEM_LAST_MODIFIED_BY_APP = 289 - BACKFILL_LINE_ITEM_LIFETIME_CLICKS = 283 - BACKFILL_LINE_ITEM_LIFETIME_IMPRESSIONS = 282 - BACKFILL_LINE_ITEM_LIFETIME_VIEWABLE_IMPRESSIONS = 284 - BACKFILL_LINE_ITEM_MAKEGOOD = 276 - BACKFILL_LINE_ITEM_NAME = 299 - BACKFILL_LINE_ITEM_NON_CPD_BOOKED_REVENUE = 286 - BACKFILL_LINE_ITEM_OPTIMIZABLE = 277 - BACKFILL_LINE_ITEM_PRIMARY_GOAL_TYPE = 262 - BACKFILL_LINE_ITEM_PRIMARY_GOAL_TYPE_NAME = 263 - BACKFILL_LINE_ITEM_PRIMARY_GOAL_UNIT_TYPE = 260 - BACKFILL_LINE_ITEM_PRIMARY_GOAL_UNIT_TYPE_NAME = 261 - BACKFILL_LINE_ITEM_PRIORITY = 266 - BACKFILL_LINE_ITEM_RESERVATION_STATUS = 306 - BACKFILL_LINE_ITEM_RESERVATION_STATUS_NAME = 307 - BACKFILL_LINE_ITEM_START_DATE = 268 - BACKFILL_LINE_ITEM_START_DATE_TIME = 270 - BACKFILL_LINE_ITEM_TYPE = 300 - BACKFILL_LINE_ITEM_TYPE_NAME = 301 - BACKFILL_LINE_ITEM_UNLIMITED_END = 271 - BACKFILL_LINE_ITEM_VALUE_COST_PER_UNIT = 275 - BACKFILL_LINE_ITEM_WEB_PROPERTY_CODE = 287 - BACKFILL_MASTER_COMPANION_CREATIVE_ID = 372 - BACKFILL_MASTER_COMPANION_CREATIVE_NAME = 373 - BACKFILL_ORDER_AGENCY = 313 - BACKFILL_ORDER_AGENCY_ID = 314 - BACKFILL_ORDER_BOOKED_CPC = 315 - BACKFILL_ORDER_BOOKED_CPM = 316 - BACKFILL_ORDER_DELIVERY_STATUS = 340 - BACKFILL_ORDER_DELIVERY_STATUS_NAME = 341 - BACKFILL_ORDER_END_DATE = 317 - BACKFILL_ORDER_END_DATE_TIME = 319 - BACKFILL_ORDER_EXTERNAL_ID = 320 - BACKFILL_ORDER_ID = 338 - BACKFILL_ORDER_LABELS = 334 - BACKFILL_ORDER_LABEL_IDS = 335 - BACKFILL_ORDER_LIFETIME_CLICKS = 322 - BACKFILL_ORDER_LIFETIME_IMPRESSIONS = 323 - BACKFILL_ORDER_NAME = 339 - BACKFILL_ORDER_PO_NUMBER = 324 - BACKFILL_ORDER_PROGRAMMATIC = 321 - BACKFILL_ORDER_SALESPERSON = 325 - BACKFILL_ORDER_SECONDARY_SALESPEOPLE = 329 - BACKFILL_ORDER_SECONDARY_SALESPEOPLE_ID = 328 - BACKFILL_ORDER_SECONDARY_TRAFFICKERS = 331 - BACKFILL_ORDER_SECONDARY_TRAFFICKERS_ID = 330 - BACKFILL_ORDER_START_DATE = 332 - BACKFILL_ORDER_START_DATE_TIME = 333 - BACKFILL_ORDER_TRAFFICKER = 326 - BACKFILL_ORDER_TRAFFICKER_ID = 327 - BACKFILL_ORDER_UNLIMITED_END = 318 - BACKFILL_PROGRAMMATIC_BUYER_ID = 336 - BACKFILL_PROGRAMMATIC_BUYER_NAME = 337 - BRANDING_TYPE = 383 - BRANDING_TYPE_NAME = 384 - BROWSER_CATEGORY = 119 - BROWSER_CATEGORY_NAME = 120 - BROWSER_ID = 235 - BROWSER_NAME = 236 - CARRIER_ID = 369 - CARRIER_NAME = 368 - CLASSIFIED_ADVERTISER_ID = 133 - CLASSIFIED_ADVERTISER_NAME = 134 - CLASSIFIED_BRAND_ID = 243 - CLASSIFIED_BRAND_NAME = 244 - CONTENT_ID = 246 - CONTENT_NAME = 247 - COUNTRY_ID = 11 - COUNTRY_NAME = 12 - CREATIVE_BILLING_TYPE = 366 - CREATIVE_BILLING_TYPE_NAME = 367 - CREATIVE_CLICK_THROUGH_URL = 174 - CREATIVE_ID = 138 - CREATIVE_NAME = 139 - CREATIVE_TECHNOLOGY = 148 - CREATIVE_TECHNOLOGY_NAME = 149 - CREATIVE_THIRD_PARTY_VENDOR = 361 - CREATIVE_TYPE = 344 - CREATIVE_TYPE_NAME = 345 - DATE = 3 - DAY_OF_WEEK = 4 - DEMAND_CHANNEL = 9 - DEMAND_CHANNEL_NAME = 10 - DEMAND_SUBCHANNEL = 22 - DEMAND_SUBCHANNEL_NAME = 23 - DEVICE = 226 - DEVICE_CATEGORY = 15 - DEVICE_CATEGORY_NAME = 16 - DEVICE_NAME = 225 - EXCHANGE_THIRD_PARTY_COMPANY_ID = 185 - EXCHANGE_THIRD_PARTY_COMPANY_NAME = 186 - FIRST_LOOK_PRICING_RULE_ID = 248 - FIRST_LOOK_PRICING_RULE_NAME = 249 - HOUR = 100 - INTERACTION_TYPE = 223 - INTERACTION_TYPE_NAME = 224 - INVENTORY_FORMAT = 17 - INVENTORY_FORMAT_NAME = 18 - INVENTORY_TYPE = 19 - INVENTORY_TYPE_NAME = 20 - IS_ADX_DIRECT = 382 - IS_FIRST_LOOK_DEAL = 401 - KEY_VALUES_ID = 214 - KEY_VALUES_NAME = 215 - LINE_ITEM_ARCHIVED = 188 - LINE_ITEM_COMPANION_DELIVERY_OPTION = 204 - LINE_ITEM_COMPANION_DELIVERY_OPTION_NAME = 205 - LINE_ITEM_COMPUTED_STATUS = 250 - LINE_ITEM_COMPUTED_STATUS_NAME = 251 - LINE_ITEM_CONTRACTED_QUANTITY = 92 - LINE_ITEM_COST_PER_UNIT = 85 - LINE_ITEM_COST_TYPE = 212 - LINE_ITEM_COST_TYPE_NAME = 213 - LINE_ITEM_CREATIVE_END_DATE = 176 - LINE_ITEM_CREATIVE_ROTATION_TYPE = 189 - LINE_ITEM_CREATIVE_ROTATION_TYPE_NAME = 190 - LINE_ITEM_CREATIVE_START_DATE = 175 - LINE_ITEM_CURRENCY_CODE = 180 - LINE_ITEM_DELIVERY_INDICATOR = 87 - LINE_ITEM_DELIVERY_RATE_TYPE = 191 - LINE_ITEM_DELIVERY_RATE_TYPE_NAME = 192 - LINE_ITEM_DISCOUNT_ABSOLUTE = 195 - LINE_ITEM_DISCOUNT_PERCENTAGE = 196 - LINE_ITEM_END_DATE = 81 - LINE_ITEM_END_DATE_TIME = 83 - LINE_ITEM_ENVIRONMENT_TYPE = 201 - LINE_ITEM_ENVIRONMENT_TYPE_NAME = 202 - LINE_ITEM_EXTERNAL_DEAL_ID = 97 - LINE_ITEM_EXTERNAL_ID = 86 - LINE_ITEM_FREQUENCY_CAP = 256 - LINE_ITEM_ID = 1 - LINE_ITEM_LAST_MODIFIED_BY_APP = 181 - LINE_ITEM_LIFETIME_CLICKS = 95 - LINE_ITEM_LIFETIME_IMPRESSIONS = 94 - LINE_ITEM_LIFETIME_VIEWABLE_IMPRESSIONS = 96 - LINE_ITEM_MAKEGOOD = 89 - LINE_ITEM_NAME = 2 - LINE_ITEM_NON_CPD_BOOKED_REVENUE = 98 - LINE_ITEM_OPTIMIZABLE = 90 - LINE_ITEM_PRIMARY_GOAL_TYPE = 210 - LINE_ITEM_PRIMARY_GOAL_TYPE_NAME = 211 - LINE_ITEM_PRIMARY_GOAL_UNITS_ABSOLUTE = 93 - LINE_ITEM_PRIMARY_GOAL_UNITS_PERCENTAGE = 396 - LINE_ITEM_PRIMARY_GOAL_UNIT_TYPE = 208 - LINE_ITEM_PRIMARY_GOAL_UNIT_TYPE_NAME = 209 - LINE_ITEM_PRIORITY = 24 - LINE_ITEM_RESERVATION_STATUS = 304 - LINE_ITEM_RESERVATION_STATUS_NAME = 305 - LINE_ITEM_START_DATE = 82 - LINE_ITEM_START_DATE_TIME = 84 - LINE_ITEM_TYPE = 193 - LINE_ITEM_TYPE_NAME = 194 - LINE_ITEM_UNLIMITED_END = 187 - LINE_ITEM_VALUE_COST_PER_UNIT = 88 - LINE_ITEM_WEB_PROPERTY_CODE = 179 - MASTER_COMPANION_CREATIVE_ID = 140 - MASTER_COMPANION_CREATIVE_NAME = 141 - MOBILE_APP_FREE = 128 - MOBILE_APP_ICON_URL = 129 - MOBILE_APP_ID = 123 - MOBILE_APP_NAME = 127 - MOBILE_APP_OWNERSHIP_STATUS = 311 - MOBILE_APP_OWNERSHIP_STATUS_NAME = 312 - MOBILE_APP_STORE = 125 - MOBILE_APP_STORE_NAME = 245 - MOBILE_INVENTORY_TYPE = 99 - MOBILE_INVENTORY_TYPE_NAME = 21 - MOBILE_SDK_VERSION_NAME = 130 - MONTH_YEAR = 6 - NATIVE_AD_FORMAT_ID = 255 - NATIVE_AD_FORMAT_NAME = 254 - NATIVE_STYLE_ID = 253 - NATIVE_STYLE_NAME = 252 - OPERATING_SYSTEM_CATEGORY = 117 - OPERATING_SYSTEM_CATEGORY_NAME = 118 - OPERATING_SYSTEM_VERSION_ID = 238 - OPERATING_SYSTEM_VERSION_NAME = 237 - ORDER_AGENCY = 150 - ORDER_AGENCY_ID = 151 - ORDER_BOOKED_CPC = 152 - ORDER_BOOKED_CPM = 153 - ORDER_DELIVERY_STATUS = 231 - ORDER_DELIVERY_STATUS_NAME = 239 - ORDER_END_DATE = 154 - ORDER_END_DATE_TIME = 155 - ORDER_EXTERNAL_ID = 156 - ORDER_ID = 7 - ORDER_LABELS = 170 - ORDER_LABEL_IDS = 171 - ORDER_LIFETIME_CLICKS = 158 - ORDER_LIFETIME_IMPRESSIONS = 159 - ORDER_NAME = 8 - ORDER_PO_NUMBER = 160 - ORDER_PROGRAMMATIC = 157 - ORDER_SALESPERSON = 161 - ORDER_SECONDARY_SALESPEOPLE = 164 - ORDER_SECONDARY_SALESPEOPLE_ID = 165 - ORDER_SECONDARY_TRAFFICKERS = 166 - ORDER_SECONDARY_TRAFFICKERS_ID = 167 - ORDER_START_DATE = 168 - ORDER_START_DATE_TIME = 169 - ORDER_TRAFFICKER = 162 - ORDER_TRAFFICKER_ID = 163 - ORDER_UNLIMITED_END = 203 - PLACEMENT_ID = 113 - PLACEMENT_ID_ALL = 144 - PLACEMENT_NAME = 114 - PLACEMENT_NAME_ALL = 145 - PLACEMENT_STATUS = 362 - PLACEMENT_STATUS_ALL = 363 - PLACEMENT_STATUS_NAME = 364 - PLACEMENT_STATUS_NAME_ALL = 365 - PROGRAMMATIC_BUYER_ID = 240 - PROGRAMMATIC_BUYER_NAME = 241 - PROGRAMMATIC_CHANNEL = 13 - PROGRAMMATIC_CHANNEL_NAME = 14 - RENDERED_CREATIVE_SIZE = 343 - REQUESTED_AD_SIZES = 352 - REQUEST_TYPE = 146 - REQUEST_TYPE_NAME = 147 - SERVER_SIDE_UNWRAPPING_ELIGIBLE = 597 - SITE = 387 - TARGETING_ID = 232 - TARGETING_NAME = 233 - TARGETING_TYPE = 385 - TARGETING_TYPE_NAME = 386 - TRAFFIC_SOURCE = 388 - TRAFFIC_SOURCE_NAME = 389 - UNIFIED_PRICING_RULE_ID = 393 - UNIFIED_PRICING_RULE_NAME = 394 - VIDEO_PLCMT = 172 - VIDEO_PLCMT_NAME = 173 - WEEK = 5 - YIELD_GROUP_BUYER_NAME = 184 - YIELD_GROUP_ID = 182 - YIELD_GROUP_NAME = 183 - LINE_ITEM_CUSTOM_FIELD_0_OPTION_ID = 10000 - LINE_ITEM_CUSTOM_FIELD_1_OPTION_ID = 10001 - LINE_ITEM_CUSTOM_FIELD_2_OPTION_ID = 10002 - LINE_ITEM_CUSTOM_FIELD_3_OPTION_ID = 10003 - LINE_ITEM_CUSTOM_FIELD_4_OPTION_ID = 10004 - LINE_ITEM_CUSTOM_FIELD_5_OPTION_ID = 10005 - LINE_ITEM_CUSTOM_FIELD_6_OPTION_ID = 10006 - LINE_ITEM_CUSTOM_FIELD_7_OPTION_ID = 10007 - LINE_ITEM_CUSTOM_FIELD_8_OPTION_ID = 10008 - LINE_ITEM_CUSTOM_FIELD_9_OPTION_ID = 10009 - LINE_ITEM_CUSTOM_FIELD_10_OPTION_ID = 10010 - LINE_ITEM_CUSTOM_FIELD_11_OPTION_ID = 10011 - LINE_ITEM_CUSTOM_FIELD_12_OPTION_ID = 10012 - LINE_ITEM_CUSTOM_FIELD_13_OPTION_ID = 10013 - LINE_ITEM_CUSTOM_FIELD_14_OPTION_ID = 10014 - LINE_ITEM_CUSTOM_FIELD_0_VALUE = 11000 - LINE_ITEM_CUSTOM_FIELD_1_VALUE = 11001 - LINE_ITEM_CUSTOM_FIELD_2_VALUE = 11002 - LINE_ITEM_CUSTOM_FIELD_3_VALUE = 11003 - LINE_ITEM_CUSTOM_FIELD_4_VALUE = 11004 - LINE_ITEM_CUSTOM_FIELD_5_VALUE = 11005 - LINE_ITEM_CUSTOM_FIELD_6_VALUE = 11006 - LINE_ITEM_CUSTOM_FIELD_7_VALUE = 11007 - LINE_ITEM_CUSTOM_FIELD_8_VALUE = 11008 - LINE_ITEM_CUSTOM_FIELD_9_VALUE = 11009 - LINE_ITEM_CUSTOM_FIELD_10_VALUE = 11010 - LINE_ITEM_CUSTOM_FIELD_11_VALUE = 11011 - LINE_ITEM_CUSTOM_FIELD_12_VALUE = 11012 - LINE_ITEM_CUSTOM_FIELD_13_VALUE = 11013 - LINE_ITEM_CUSTOM_FIELD_14_VALUE = 11014 - ORDER_CUSTOM_FIELD_0_OPTION_ID = 12000 - ORDER_CUSTOM_FIELD_1_OPTION_ID = 12001 - ORDER_CUSTOM_FIELD_2_OPTION_ID = 12002 - ORDER_CUSTOM_FIELD_3_OPTION_ID = 12003 - ORDER_CUSTOM_FIELD_4_OPTION_ID = 12004 - ORDER_CUSTOM_FIELD_5_OPTION_ID = 12005 - ORDER_CUSTOM_FIELD_6_OPTION_ID = 12006 - ORDER_CUSTOM_FIELD_7_OPTION_ID = 12007 - ORDER_CUSTOM_FIELD_8_OPTION_ID = 12008 - ORDER_CUSTOM_FIELD_9_OPTION_ID = 12009 - ORDER_CUSTOM_FIELD_10_OPTION_ID = 12010 - ORDER_CUSTOM_FIELD_11_OPTION_ID = 12011 - ORDER_CUSTOM_FIELD_12_OPTION_ID = 12012 - ORDER_CUSTOM_FIELD_13_OPTION_ID = 12013 - ORDER_CUSTOM_FIELD_14_OPTION_ID = 12014 - ORDER_CUSTOM_FIELD_0_VALUE = 13000 - ORDER_CUSTOM_FIELD_1_VALUE = 13001 - ORDER_CUSTOM_FIELD_2_VALUE = 13002 - ORDER_CUSTOM_FIELD_3_VALUE = 13003 - ORDER_CUSTOM_FIELD_4_VALUE = 13004 - ORDER_CUSTOM_FIELD_5_VALUE = 13005 - ORDER_CUSTOM_FIELD_6_VALUE = 13006 - ORDER_CUSTOM_FIELD_7_VALUE = 13007 - ORDER_CUSTOM_FIELD_8_VALUE = 13008 - ORDER_CUSTOM_FIELD_9_VALUE = 13009 - ORDER_CUSTOM_FIELD_10_VALUE = 13010 - ORDER_CUSTOM_FIELD_11_VALUE = 13011 - ORDER_CUSTOM_FIELD_12_VALUE = 13012 - ORDER_CUSTOM_FIELD_13_VALUE = 13013 - ORDER_CUSTOM_FIELD_14_VALUE = 13014 - CREATIVE_CUSTOM_FIELD_0_OPTION_ID = 14000 - CREATIVE_CUSTOM_FIELD_1_OPTION_ID = 14001 - CREATIVE_CUSTOM_FIELD_2_OPTION_ID = 14002 - CREATIVE_CUSTOM_FIELD_3_OPTION_ID = 14003 - CREATIVE_CUSTOM_FIELD_4_OPTION_ID = 14004 - CREATIVE_CUSTOM_FIELD_5_OPTION_ID = 14005 - CREATIVE_CUSTOM_FIELD_6_OPTION_ID = 14006 - CREATIVE_CUSTOM_FIELD_7_OPTION_ID = 14007 - CREATIVE_CUSTOM_FIELD_8_OPTION_ID = 14008 - CREATIVE_CUSTOM_FIELD_9_OPTION_ID = 14009 - CREATIVE_CUSTOM_FIELD_10_OPTION_ID = 14010 - CREATIVE_CUSTOM_FIELD_11_OPTION_ID = 14011 - CREATIVE_CUSTOM_FIELD_12_OPTION_ID = 14012 - CREATIVE_CUSTOM_FIELD_13_OPTION_ID = 14013 - CREATIVE_CUSTOM_FIELD_14_OPTION_ID = 14014 - CREATIVE_CUSTOM_FIELD_0_VALUE = 15000 - CREATIVE_CUSTOM_FIELD_1_VALUE = 15001 - CREATIVE_CUSTOM_FIELD_2_VALUE = 15002 - CREATIVE_CUSTOM_FIELD_3_VALUE = 15003 - CREATIVE_CUSTOM_FIELD_4_VALUE = 15004 - CREATIVE_CUSTOM_FIELD_5_VALUE = 15005 - CREATIVE_CUSTOM_FIELD_6_VALUE = 15006 - CREATIVE_CUSTOM_FIELD_7_VALUE = 15007 - CREATIVE_CUSTOM_FIELD_8_VALUE = 15008 - CREATIVE_CUSTOM_FIELD_9_VALUE = 15009 - CREATIVE_CUSTOM_FIELD_10_VALUE = 15010 - CREATIVE_CUSTOM_FIELD_11_VALUE = 15011 - CREATIVE_CUSTOM_FIELD_12_VALUE = 15012 - CREATIVE_CUSTOM_FIELD_13_VALUE = 15013 - CREATIVE_CUSTOM_FIELD_14_VALUE = 15014 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_0_OPTION_ID = 16000 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_1_OPTION_ID = 16001 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_2_OPTION_ID = 16002 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_3_OPTION_ID = 16003 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_4_OPTION_ID = 16004 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_5_OPTION_ID = 16005 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_6_OPTION_ID = 16006 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_7_OPTION_ID = 16007 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_8_OPTION_ID = 16008 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_9_OPTION_ID = 16009 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_10_OPTION_ID = 16010 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_11_OPTION_ID = 16011 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_12_OPTION_ID = 16012 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_13_OPTION_ID = 16013 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_14_OPTION_ID = 16014 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_0_VALUE = 17000 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_1_VALUE = 17001 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_2_VALUE = 17002 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_3_VALUE = 17003 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_4_VALUE = 17004 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_5_VALUE = 17005 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_6_VALUE = 17006 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_7_VALUE = 17007 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_8_VALUE = 17008 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_9_VALUE = 17009 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_10_VALUE = 17010 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_11_VALUE = 17011 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_12_VALUE = 17012 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_13_VALUE = 17013 - BACKFILL_LINE_ITEM_CUSTOM_FIELD_14_VALUE = 17014 - BACKFILL_ORDER_CUSTOM_FIELD_0_OPTION_ID = 18000 - BACKFILL_ORDER_CUSTOM_FIELD_1_OPTION_ID = 18001 - BACKFILL_ORDER_CUSTOM_FIELD_2_OPTION_ID = 18002 - BACKFILL_ORDER_CUSTOM_FIELD_3_OPTION_ID = 18003 - BACKFILL_ORDER_CUSTOM_FIELD_4_OPTION_ID = 18004 - BACKFILL_ORDER_CUSTOM_FIELD_5_OPTION_ID = 18005 - BACKFILL_ORDER_CUSTOM_FIELD_6_OPTION_ID = 18006 - BACKFILL_ORDER_CUSTOM_FIELD_7_OPTION_ID = 18007 - BACKFILL_ORDER_CUSTOM_FIELD_8_OPTION_ID = 18008 - BACKFILL_ORDER_CUSTOM_FIELD_9_OPTION_ID = 18009 - BACKFILL_ORDER_CUSTOM_FIELD_10_OPTION_ID = 18010 - BACKFILL_ORDER_CUSTOM_FIELD_11_OPTION_ID = 18011 - BACKFILL_ORDER_CUSTOM_FIELD_12_OPTION_ID = 18012 - BACKFILL_ORDER_CUSTOM_FIELD_13_OPTION_ID = 18013 - BACKFILL_ORDER_CUSTOM_FIELD_14_OPTION_ID = 18014 - BACKFILL_ORDER_CUSTOM_FIELD_0_VALUE = 19000 - BACKFILL_ORDER_CUSTOM_FIELD_1_VALUE = 19001 - BACKFILL_ORDER_CUSTOM_FIELD_2_VALUE = 19002 - BACKFILL_ORDER_CUSTOM_FIELD_3_VALUE = 19003 - BACKFILL_ORDER_CUSTOM_FIELD_4_VALUE = 19004 - BACKFILL_ORDER_CUSTOM_FIELD_5_VALUE = 19005 - BACKFILL_ORDER_CUSTOM_FIELD_6_VALUE = 19006 - BACKFILL_ORDER_CUSTOM_FIELD_7_VALUE = 19007 - BACKFILL_ORDER_CUSTOM_FIELD_8_VALUE = 19008 - BACKFILL_ORDER_CUSTOM_FIELD_9_VALUE = 19009 - BACKFILL_ORDER_CUSTOM_FIELD_10_VALUE = 19010 - BACKFILL_ORDER_CUSTOM_FIELD_11_VALUE = 19011 - BACKFILL_ORDER_CUSTOM_FIELD_12_VALUE = 19012 - BACKFILL_ORDER_CUSTOM_FIELD_13_VALUE = 19013 - BACKFILL_ORDER_CUSTOM_FIELD_14_VALUE = 19014 - BACKFILL_CREATIVE_CUSTOM_FIELD_0_OPTION_ID = 20000 - BACKFILL_CREATIVE_CUSTOM_FIELD_1_OPTION_ID = 20001 - BACKFILL_CREATIVE_CUSTOM_FIELD_2_OPTION_ID = 20002 - BACKFILL_CREATIVE_CUSTOM_FIELD_3_OPTION_ID = 20003 - BACKFILL_CREATIVE_CUSTOM_FIELD_4_OPTION_ID = 20004 - BACKFILL_CREATIVE_CUSTOM_FIELD_5_OPTION_ID = 20005 - BACKFILL_CREATIVE_CUSTOM_FIELD_6_OPTION_ID = 20006 - BACKFILL_CREATIVE_CUSTOM_FIELD_7_OPTION_ID = 20007 - BACKFILL_CREATIVE_CUSTOM_FIELD_8_OPTION_ID = 20008 - BACKFILL_CREATIVE_CUSTOM_FIELD_9_OPTION_ID = 20009 - BACKFILL_CREATIVE_CUSTOM_FIELD_10_OPTION_ID = 20010 - BACKFILL_CREATIVE_CUSTOM_FIELD_11_OPTION_ID = 20011 - BACKFILL_CREATIVE_CUSTOM_FIELD_12_OPTION_ID = 20012 - BACKFILL_CREATIVE_CUSTOM_FIELD_13_OPTION_ID = 20013 - BACKFILL_CREATIVE_CUSTOM_FIELD_14_OPTION_ID = 20014 - BACKFILL_CREATIVE_CUSTOM_FIELD_0_VALUE = 21000 - BACKFILL_CREATIVE_CUSTOM_FIELD_1_VALUE = 21001 - BACKFILL_CREATIVE_CUSTOM_FIELD_2_VALUE = 21002 - BACKFILL_CREATIVE_CUSTOM_FIELD_3_VALUE = 21003 - BACKFILL_CREATIVE_CUSTOM_FIELD_4_VALUE = 21004 - BACKFILL_CREATIVE_CUSTOM_FIELD_5_VALUE = 21005 - BACKFILL_CREATIVE_CUSTOM_FIELD_6_VALUE = 21006 - BACKFILL_CREATIVE_CUSTOM_FIELD_7_VALUE = 21007 - BACKFILL_CREATIVE_CUSTOM_FIELD_8_VALUE = 21008 - BACKFILL_CREATIVE_CUSTOM_FIELD_9_VALUE = 21009 - BACKFILL_CREATIVE_CUSTOM_FIELD_10_VALUE = 21010 - BACKFILL_CREATIVE_CUSTOM_FIELD_11_VALUE = 21011 - BACKFILL_CREATIVE_CUSTOM_FIELD_12_VALUE = 21012 - BACKFILL_CREATIVE_CUSTOM_FIELD_13_VALUE = 21013 - BACKFILL_CREATIVE_CUSTOM_FIELD_14_VALUE = 21014 - CUSTOM_DIMENSION_0_VALUE_ID = 100000 - CUSTOM_DIMENSION_1_VALUE_ID = 100001 - CUSTOM_DIMENSION_2_VALUE_ID = 100002 - CUSTOM_DIMENSION_3_VALUE_ID = 100003 - CUSTOM_DIMENSION_4_VALUE_ID = 100004 - CUSTOM_DIMENSION_5_VALUE_ID = 100005 - CUSTOM_DIMENSION_6_VALUE_ID = 100006 - CUSTOM_DIMENSION_7_VALUE_ID = 100007 - CUSTOM_DIMENSION_8_VALUE_ID = 100008 - CUSTOM_DIMENSION_9_VALUE_ID = 100009 - CUSTOM_DIMENSION_0_VALUE = 101000 - CUSTOM_DIMENSION_1_VALUE = 101001 - CUSTOM_DIMENSION_2_VALUE = 101002 - CUSTOM_DIMENSION_3_VALUE = 101003 - CUSTOM_DIMENSION_4_VALUE = 101004 - CUSTOM_DIMENSION_5_VALUE = 101005 - CUSTOM_DIMENSION_6_VALUE = 101006 - CUSTOM_DIMENSION_7_VALUE = 101007 - CUSTOM_DIMENSION_8_VALUE = 101008 - CUSTOM_DIMENSION_9_VALUE = 101009 - - class Metric(proto.Enum): - r"""Reporting metrics. - - Values: - METRIC_UNSPECIFIED (0): - Default value. This value is unused. - ACTIVE_VIEW_AVERAGE_VIEWABLE_TIME (61): - Active View total average time in seconds - that specific impressions are reported as being - viewable. - ACTIVE_VIEW_ELIGIBLE_IMPRESSIONS (58): - Total number of impressions that were - eligible to measure viewability. - ACTIVE_VIEW_MEASURABLE_IMPRESSIONS (57): - The total number of impressions that were - sampled and measured by active view. - ACTIVE_VIEW_MEASURABLE_IMPRESSIONS_RATE (60): - The percentage of total impressions that were - measurable by active view (out of all the total - impressions sampled for active view). - ACTIVE_VIEW_VIEWABLE_IMPRESSIONS (56): - The total number of impressions viewed on the - user's screen. - ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_RATE (59): - The percentage of total impressions viewed on - the user's screen (out of the total impressions - measurable by active view). - ADSENSE_ACTIVE_VIEW_AVERAGE_VIEWABLE_TIME (73): - Active View AdSense average time in seconds - that specific impressions are reported as being - viewable. - ADSENSE_ACTIVE_VIEW_ELIGIBLE_IMPRESSIONS (70): - Total number of impressions delivered by - AdSense that were eligible to measure - viewability. - ADSENSE_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS (69): - The number of impressions delivered by - AdSense that were sampled, and measurable by - active view. - ADSENSE_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS_RATE (72): - The percentage of impressions delivered by - AdSense that were measurable by active view (out - of all AdSense impressions sampled for active - view). - ADSENSE_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS (68): - The number of impressions delivered by - AdSense viewed on the user's screen. - ADSENSE_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_RATE (71): - The percentage of impressions delivered by - AdSense viewed on the user's screen (out of - AdSense impressions measurable by active view). - ADSENSE_AVERAGE_ECPM (26): - The average effective - cost-per-thousand-impressions earned from the - ads delivered by AdSense through line item - dynamic allocation. - ADSENSE_CLICKS (23): - Number of clicks delivered by AdSense demand - channel. - ADSENSE_CTR (24): - The ratio of impressions served by AdSense - that resulted in users clicking on an ad. The - clickthrough rate (CTR) is updated nightly. The - AdSense CTR is calculated as: (AdSense clicks / - AdSense impressions). - ADSENSE_IMPRESSIONS (22): - Total impressions delivered by AdSense. - ADSENSE_PERCENT_CLICKS (28): - Ratio of clicks delivered by AdSense through - line item dynamic allocation in relation to the - total clicks delivered. - ADSENSE_PERCENT_IMPRESSIONS (27): - Ratio of impressions delivered by AdSense - through line item dynamic allocation in relation - to the total impressions delivered. - ADSENSE_PERCENT_REVENUE (29): - Ratio of revenue generated by AdSense through - line item dynamic allocation in relation to the - total revenue. - ADSENSE_PERCENT_REVENUE_WITHOUT_CPD (30): - Ratio of revenue generated by AdSense through - line item dynamic allocation in relation to the - total revenue (excluding CPD). - ADSENSE_RESPONSES_SERVED (41): - The total number of times that an AdSense ad - is delivered. - ADSENSE_REVENUE (25): - Revenue generated from AdSense through line - item dynamic allocation, calculated in the - network's currency and time zone. - AD_EXCHANGE_ACTIVE_VIEW_AVERAGE_VIEWABLE_TIME (79): - Active View AdExchange average time in - seconds that specific impressions are reported - as being viewable. - AD_EXCHANGE_ACTIVE_VIEW_ELIGIBLE_IMPRESSIONS (76): - Total number of impressions delivered by Ad - Exchange that were eligible to measure - viewability. - AD_EXCHANGE_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS (75): - The number of impressions delivered by Ad - Exchange that were sampled, and measurable by - active view. - AD_EXCHANGE_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS_RATE (78): - The percentage of impressions delivered by Ad - Exchange that were measurable by active view - (out of all Ad Exchange impressions sampled for - active view). - AD_EXCHANGE_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS (74): - The number of impressions delivered by Ad - Exchange viewed on the user's screen. - AD_EXCHANGE_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_RATE (77): - The percentage of impressions delivered by Ad - Exchange viewed on the user's screen (out of Ad - Exchange impressions measurable by active view). - AD_EXCHANGE_AVERAGE_ECPM (18): - The average effective - cost-per-thousand-impressions earned from the - ads delivered by Ad Exchange through line item - dynamic allocation. - AD_EXCHANGE_CLICKS (15): - Number of clicks delivered by the Ad - Exchange. - AD_EXCHANGE_CTR (16): - The ratio of impressions served by the Ad - Exchange that resulted in users clicking on an - ad. The clickthrough rate (CTR) is updated - nightly. Ad Exchange CTR is calculated as: (Ad - Exchange clicks / Ad Exchange impressions). - AD_EXCHANGE_IMPRESSIONS (14): - Total impressions delivered by the Ad - Exchange. - AD_EXCHANGE_PERCENT_CLICKS (20): - Ratio of clicks delivered by Ad Exchange - through line item dynamic allocation in relation - to the total clicks delivered. - AD_EXCHANGE_PERCENT_IMPRESSIONS (19): - Ratio of impressions delivered by Ad Exchange - through line item dynamic allocation in relation - to the total impressions delivered. - AD_EXCHANGE_PERCENT_REVENUE (21): - Ratio of revenue generated by Ad Exchange - through line item dynamic allocation in relation - to the total revenue. - AD_EXCHANGE_PERCENT_REVENUE_WITHOUT_CPD (31): - Ratio of revenue generated by Ad Exchange - through line item dynamic allocation in relation - to the total revenue (excluding CPD). - AD_EXCHANGE_RESPONSES_SERVED (42): - The total number of times that an Ad Exchange - ad is delivered. - AD_EXCHANGE_REVENUE (17): - Revenue generated from the Ad Exchange - through line item dynamic allocation, calculated - in your network's currency and time zone. - AD_REQUESTS (38): - The total number of times that an ad request - is sent to the ad server including dynamic - allocation. - AD_SERVER_ACTIVE_VIEW_AVERAGE_VIEWABLE_TIME (67): - Active View ad server average time in seconds - that specific impressions are reported as being - viewable. - AD_SERVER_ACTIVE_VIEW_ELIGIBLE_IMPRESSIONS (64): - Total number of impressions delivered by the - ad server that were eligible to measure - viewability. - AD_SERVER_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS (63): - The number of impressions delivered by the ad - server that were sampled, and measurable by - active view. - AD_SERVER_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS_RATE (66): - The percentage of impressions delivered by - the ad server that were measurable by active - view (out of all the ad server impressions - sampled for active view). - AD_SERVER_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS (62): - The number of impressions delivered by the ad - server viewed on the user's screen. - AD_SERVER_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_RATE (65): - The percentage of impressions delivered by - the ad server viewed on the user's screen (out - of the ad server impressions measurable by - active view). - AD_SERVER_AVERAGE_ECPM (34): - Average effective - cost-per-thousand-impressions earned from the - ads delivered by the Google Ad Manager server. - AD_SERVER_AVERAGE_ECPM_WITHOUT_CPD (10): - Average effective - cost-per-thousand-impressions earned from the - ads delivered by the Google Ad Manager server, - excluding CPD value. - AD_SERVER_BEGIN_TO_RENDER_IMPRESSIONS (262): - Total raw impressions counted when creative - begins to render or the first frame of a video - is shown. - AD_SERVER_CLICKS (7): - Total clicks served by the Google Ad Manager - server. It usually takes about 30 minutes for - new clicks to be recorded and added to the total - displayed in reporting. - AD_SERVER_CPD_REVENUE (32): - CPD revenue earned, calculated in your - network's currency, for the ads delivered by the - Google Ad Manager server. Sum of all booked - revenue. - AD_SERVER_CTR (8): - Ratio of impressions served by the Google Ad - Manager server that resulted in users clicking - on an ad. The clickthrough rate (CTR) is updated - nightly. The ad server CTR is calculated as: (Ad - server clicks / Ad server impressions). - AD_SERVER_IMPRESSIONS (6): - Total impressions delivered by the Ad Server. - AD_SERVER_PERCENT_CLICKS (12): - Ratio of clicks delivered by the Google Ad - Manager server in relation to the total clicks - delivered. - AD_SERVER_PERCENT_IMPRESSIONS (11): - Ratio of impressions delivered by the Google - Ad Manager server in relation to the total - impressions delivered. - AD_SERVER_PERCENT_REVENUE (35): - Ratio of revenue generated by the Google Ad - Manager server in relation to the total revenue. - AD_SERVER_PERCENT_REVENUE_WITHOUT_CPD (13): - Ratio of revenue generated by the Google Ad - Manager server (excluding CPD) in relation to - the total revenue. - AD_SERVER_RESPONSES_SERVED (40): - The total number of times that an ad is - served by the ad server. - AD_SERVER_REVENUE (33): - All CPM, CPC, and CPD revenue earned, - calculated in your network's currency, for the - ads delivered by the Google Ad Manager server. - Sum of all booked revenue. - AD_SERVER_REVENUE_WITHOUT_CPD (9): - Revenue (excluding CPD) earned, calculated in - your network's currency, for the ads delivered - by the Google Ad Manager server. Sum of all - booked revenue. - AD_SERVER_TRACKED_ADS (264): - The number of tracked ads delivered by the ad - server. - AD_SERVER_UNFILTERED_BEGIN_TO_RENDER_IMPRESSIONS (261): - Total raw impressions counted when creative - begins to render or the first frame of a video - is shown, before invalid traffic filtrations by - Ad Server. - AD_SERVER_UNFILTERED_CLICKS (259): - Total clicks delivered by the Ad Server - before spam filtering. - AD_SERVER_UNFILTERED_IMPRESSIONS (260): - Total impressions delivered by the Ad Server - before spam filtering. - AD_SERVER_UNFILTERED_TRACKED_ADS (263): - The number of tracked ads delivered by the ad - server before invalid traffic filtrations. - AVERAGE_ECPM (37): - eCPM averaged across the Google Ad Manager - server, AdSense, and Ad Exchange. - AVERAGE_ECPM_WITHOUT_CPD (5): - eCPM averaged across the Google Ad Manager - server (excluding CPD), AdSense, and Ad - Exchange. - CLICKS (2): - The number of times a user clicked on an ad. - CODE_SERVED_COUNT (44): - The total number of times that the code for - an ad is served by the ad server including - dynamic allocation. - CTR (3): - For standard ads, your ad clickthrough rate - (CTR) is the number of ad clicks divided by the - number of individual ad impressions expressed as - a fraction. Ad CTR = Clicks / Ad impressions. - GOOGLE_SOLD_AUCTION_COVIEWED_IMPRESSIONS (129): - The number of coviewed impressions sold by - Google in partner sales. - GOOGLE_SOLD_AUCTION_IMPRESSIONS (128): - The number of auction impressions sold by - Google in partner sales. - GOOGLE_SOLD_COVIEWED_IMPRESSIONS (131): - The number of coviewed impressions sold by - Google in partner sales. - GOOGLE_SOLD_IMPRESSIONS (130): - The number of impressions sold by Google in - partner sales. - GOOGLE_SOLD_RESERVATION_COVIEWED_IMPRESSIONS (127): - The number of coviewed impressions sold by - Google in partner sales. - GOOGLE_SOLD_RESERVATION_IMPRESSIONS (126): - The number of reservation impressions sold by - Google in partner sales. - IMPRESSIONS (1): - Total impressions from the Google Ad Manager - server, AdSense, Ad Exchange, and yield group - partners. - PARTNER_SALES_FILLED_POD_REQUESTS (135): - The number of filled pod requests (filled by - partner or Google) in partner sales. - PARTNER_SALES_FILL_RATE (136): - The percent of filled requests to total ad - requests in partner sales. - PARTNER_SALES_PARTNER_MATCH_RATE (137): - The percent of partner filled requests to - total ad requests in partner sales. - PARTNER_SALES_QUERIES (132): - The number of queries eligible for partner - sales. - PARTNER_SALES_UNFILLED_IMPRESSIONS (133): - The number of partner unfilled impressions in - partner sales. If a pod request is not filled by - partner but filled by Google, this metric will - still count 1. - PARTNER_SALES_UNMATCHED_QUERIES (134): - The number of partner unmatched queries in - partner sales. If an ad request is not filled by - partner but filled by Google, this metric will - still count 1. - PARTNER_SOLD_CODE_SERVED (125): - The number of code served sold by partner in - partner sales. - PARTNER_SOLD_COVIEWED_IMPRESSIONS (124): - The number of coviewed impressions sold by - partner in partner sales. - PARTNER_SOLD_IMPRESSIONS (123): - The number of impressions sold by partner in - partner sales. - PROGRAMMATIC_ELIGIBLE_AD_REQUESTS (177): - The total number of ad requests eligible for - programmatic inventory, including Programmatic - Guaranteed, Preferred Deals, backfill, and open - auction. - PROGRAMMATIC_MATCH_RATE (178): - The number of programmatic responses served - divided by the number of programmatic eligible - ad requests. Includes Ad Exchange, Open Bidding, - and Preferred Deals. - PROGRAMMATIC_RESPONSES_SERVED (176): - Total number of ad responses served from programmatic demand - sources. Includes Ad Exchange, Open Bidding, and Preferred - Deals. - - Differs from AD_EXCHANGE_RESPONSES_SERVED, which doesn't - include Open Bidding ad requests. - RESPONSES_SERVED (39): - The total number of times that an ad is - served by the ad server including dynamic - allocation. - REVENUE (36): - Total amount of CPM, CPC, and CPD revenue - based on the number of units served by the - Google Ad Manager server, AdSense, Ad Exchange, - and third-party Mediation networks. - REVENUE_WITHOUT_CPD (4): - Total amount of revenue (excluding CPD) based - on the number of units served by the Google Ad - Manager server, AdSense, Ad Exchange, and - third-party Mediation networks. - SERVER_SIDE_UNWRAPPING_AVERAGE_LATENCY_MS (434): - The average latency in milliseconds across - all server-side unwrapping callout requests. - There is no special handling for error or - timeout responses. This reflects the entire - chain of a parent callout request, which may - result in multiple child callouts. This metric - is not sliced by child callout dimensions. - SERVER_SIDE_UNWRAPPING_CALLOUTS (435): - The total number of server-side unwrapping - callout requests. - SERVER_SIDE_UNWRAPPING_EMPTY_RESPONSES (436): - The total number of server-side unwrapping - callouts that returned an empty response. - Timeouts are not considered empty responses. - SERVER_SIDE_UNWRAPPING_ERROR_RESPONSES (437): - The total number of server-side unwrapping - callouts that returned an error response. - Timeouts and empty responses are not considered - errors. - SERVER_SIDE_UNWRAPPING_SUCCESSFUL_RESPONSES (438): - The total number of successfully unwrapped, - non-empty server-side wrapping callouts. - Successful unwrapping does not indicate that the - resulting creative was served. - SERVER_SIDE_UNWRAPPING_TIMEOUTS (439): - The total number of server-side unwrapping - callouts that timed out before returning a - response. - UNFILLED_IMPRESSIONS (45): - The total number of missed impressions due to - the ad servers' inability to find ads to serve - including dynamic allocation. - UNMATCHED_AD_REQUESTS (43): - The total number of times that an ad is not - returned by the ad server. - USER_MESSAGES_OFFERWALL_MESSAGES_SHOWN (121): - Number of times an Offerwall message was - shown to users. - USER_MESSAGES_OFFERWALL_SUCCESSFUL_ENGAGEMENTS (122): - The number of messages where the user gained - an entitlement. - VIDEO_INTERACTION_AVERAGE_INTERACTION_RATE (92): - The number of user interactions with a video, - on average, such as pause, full screen, mute, - etc. - VIDEO_INTERACTION_COLLAPSES (93): - The number of times a user collapses a video, - either to its original size or to a different - size. - VIDEO_INTERACTION_EXPANDS (95): - The number of times a user expands a video. - VIDEO_INTERACTION_FULL_SCREENS (96): - The number of times ad clip played in full - screen mode. - VIDEO_INTERACTION_MUTES (97): - The number of times video player was in mute - state during play of ad clip. - VIDEO_INTERACTION_PAUSES (98): - The number of times user paused ad clip. - VIDEO_INTERACTION_RESUMES (99): - The number of times the user unpaused the - video. - VIDEO_INTERACTION_REWINDS (100): - The number of times a user rewinds the video. - VIDEO_INTERACTION_UNMUTES (101): - The number of times a user unmutes the video. - VIDEO_INTERACTION_VIDEO_SKIPS (102): - The number of times a skippable video is - skipped. - VIDEO_REAL_TIME_CREATIVE_SERVES (139): - The number of total creative serves in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_100_COUNT (143): - The number of errors of type 100 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_101_COUNT (144): - The number of errors of type 101 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_102_COUNT (145): - The number of errors of type 102 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_200_COUNT (146): - The number of errors of type 200 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_201_COUNT (147): - The number of errors of type 201 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_202_COUNT (148): - The number of errors of type 202 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_203_COUNT (149): - The number of errors of type 203 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_300_COUNT (150): - The number of errors of type 300 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_301_COUNT (151): - The number of errors of type 301 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_302_COUNT (152): - The number of errors of type 302 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_303_COUNT (153): - The number of errors of type 303 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_400_COUNT (154): - The number of errors of type 400 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_401_COUNT (155): - The number of errors of type 401 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_402_COUNT (156): - The number of errors of type 402 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_403_COUNT (157): - The number of errors of type 403 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_405_COUNT (158): - The number of errors of type 405 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_406_COUNT (159): - The number of errors of type 406 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_407_COUNT (160): - The number of errors of type 407 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_408_COUNT (161): - The number of errors of type 408 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_409_COUNT (162): - The number of errors of type 409 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_410_COUNT (163): - The number of errors of type 410 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_500_COUNT (164): - The number of errors of type 500 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_501_COUNT (165): - The number of errors of type 501 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_502_COUNT (166): - The number of errors of type 502 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_503_COUNT (167): - The number of errors of type 503 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_600_COUNT (168): - The number of errors of type 600 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_601_COUNT (169): - The number of errors of type 601 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_602_COUNT (170): - The number of errors of type 602 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_603_COUNT (171): - The number of errors of type 603 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_604_COUNT (172): - The number of errors of type 604 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_900_COUNT (173): - The number of errors of type 900 in video - realtime reporting. - VIDEO_REAL_TIME_ERROR_901_COUNT (174): - The number of errors of type 901 in video - realtime reporting. - VIDEO_REAL_TIME_IMPRESSIONS (138): - The number of total impressions in video - realtime reporting. - VIDEO_REAL_TIME_MATCHED_QUERIES (140): - The number of matched queries in video - realtime reporting. - VIDEO_REAL_TIME_TOTAL_ERROR_COUNT (175): - The number of all errors in video realtime - reporting. - VIDEO_REAL_TIME_TOTAL_QUERIES (142): - The number of total queries in video realtime - reporting. - VIDEO_REAL_TIME_UNMATCHED_QUERIES (141): - The number of unmatched queries in video - realtime reporting. - VIDEO_VIEWERSHIP_AUTO_PLAYS (103): - Number of times that the publisher specified - a video ad played automatically. - VIDEO_VIEWERSHIP_AVERAGE_VIEW_RATE (104): - Average percentage of the video watched by - users. - VIDEO_VIEWERSHIP_AVERAGE_VIEW_TIME (105): - Average time(seconds) users watched the - video. - VIDEO_VIEWERSHIP_CLICK_TO_PLAYS (106): - Number of times that the publisher specified - a video ad was clicked to play. - VIDEO_VIEWERSHIP_COMPLETES (107): - The number of times the video played to - completion. - VIDEO_VIEWERSHIP_COMPLETION_RATE (108): - Percentage of times the video played to the - end. - VIDEO_VIEWERSHIP_ENGAGED_VIEWS (109): - The number of engaged views: ad is viewed to - completion or for 30s, whichever comes first. - VIDEO_VIEWERSHIP_FIRST_QUARTILES (110): - The number of times the video played to 25% - of its length. - VIDEO_VIEWERSHIP_MIDPOINTS (111): - The number of times the video reached its - midpoint during play. - VIDEO_VIEWERSHIP_SKIP_BUTTONS_SHOWN (112): - The number of times a skip button is shown in - video. - VIDEO_VIEWERSHIP_STARTS (113): - The number of impressions where the video was - played. - VIDEO_VIEWERSHIP_THIRD_QUARTILES (114): - The number of times the video played to 75% - of its length. - VIDEO_VIEWERSHIP_TOTAL_ERROR_COUNT (115): - The number of times an error occurred, such - as a VAST redirect error, a video playback - error, or an invalid response error. - VIDEO_VIEWERSHIP_TOTAL_ERROR_RATE (94): - The percentage of video error count. - VIDEO_VIEWERSHIP_VIDEO_LENGTH (116): - Duration of the video creative. - VIDEO_VIEWERSHIP_VIEW_THROUGH_RATE (117): - View-through rate represented as a - percentage. - YIELD_GROUP_AUCTIONS_WON (80): - Number of winning bids received from Open - Bidding buyers, even when the winning bid is - placed at the end of a mediation for mobile apps - chain. - YIELD_GROUP_BIDS (81): - Number of bids received from Open Bidding - buyers, regardless of whether the returned bid - competes in an auction. - YIELD_GROUP_BIDS_IN_AUCTION (82): - Number of bids received from Open Bidding - buyers that competed in the auction. - YIELD_GROUP_CALLOUTS (83): - Number of times a yield partner is asked to - return bid to fill a yield group request. - YIELD_GROUP_ESTIMATED_CPM (88): - The estimated net rate for yield groups or - individual yield group partners. - YIELD_GROUP_ESTIMATED_REVENUE (87): - Total net revenue earned by a yield group, - based upon the yield group estimated CPM and - yield group impressions recorded. - YIELD_GROUP_IMPRESSIONS (85): - Number of matched yield group requests where - a yield partner delivered their ad to publisher - inventory. - YIELD_GROUP_MEDIATION_FILL_RATE (89): - Yield group Mediation fill rate indicating - how often a network fills an ad request. - YIELD_GROUP_MEDIATION_MATCHED_QUERIES (86): - Total requests where a Mediation chain was - served. - YIELD_GROUP_MEDIATION_PASSBACKS (118): - The number of mediation chain passback across - all channels. - YIELD_GROUP_MEDIATION_THIRD_PARTY_ECPM (90): - Revenue per thousand impressions based on - data collected by Ad Manager from third-party ad - network reports. - YIELD_GROUP_SUCCESSFUL_RESPONSES (84): - Number of times a yield group buyer - successfully returned a bid in response to a - yield group callout. - """ - METRIC_UNSPECIFIED = 0 - ACTIVE_VIEW_AVERAGE_VIEWABLE_TIME = 61 - ACTIVE_VIEW_ELIGIBLE_IMPRESSIONS = 58 - ACTIVE_VIEW_MEASURABLE_IMPRESSIONS = 57 - ACTIVE_VIEW_MEASURABLE_IMPRESSIONS_RATE = 60 - ACTIVE_VIEW_VIEWABLE_IMPRESSIONS = 56 - ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_RATE = 59 - ADSENSE_ACTIVE_VIEW_AVERAGE_VIEWABLE_TIME = 73 - ADSENSE_ACTIVE_VIEW_ELIGIBLE_IMPRESSIONS = 70 - ADSENSE_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS = 69 - ADSENSE_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS_RATE = 72 - ADSENSE_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS = 68 - ADSENSE_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_RATE = 71 - ADSENSE_AVERAGE_ECPM = 26 - ADSENSE_CLICKS = 23 - ADSENSE_CTR = 24 - ADSENSE_IMPRESSIONS = 22 - ADSENSE_PERCENT_CLICKS = 28 - ADSENSE_PERCENT_IMPRESSIONS = 27 - ADSENSE_PERCENT_REVENUE = 29 - ADSENSE_PERCENT_REVENUE_WITHOUT_CPD = 30 - ADSENSE_RESPONSES_SERVED = 41 - ADSENSE_REVENUE = 25 - AD_EXCHANGE_ACTIVE_VIEW_AVERAGE_VIEWABLE_TIME = 79 - AD_EXCHANGE_ACTIVE_VIEW_ELIGIBLE_IMPRESSIONS = 76 - AD_EXCHANGE_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS = 75 - AD_EXCHANGE_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS_RATE = 78 - AD_EXCHANGE_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS = 74 - AD_EXCHANGE_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_RATE = 77 - AD_EXCHANGE_AVERAGE_ECPM = 18 - AD_EXCHANGE_CLICKS = 15 - AD_EXCHANGE_CTR = 16 - AD_EXCHANGE_IMPRESSIONS = 14 - AD_EXCHANGE_PERCENT_CLICKS = 20 - AD_EXCHANGE_PERCENT_IMPRESSIONS = 19 - AD_EXCHANGE_PERCENT_REVENUE = 21 - AD_EXCHANGE_PERCENT_REVENUE_WITHOUT_CPD = 31 - AD_EXCHANGE_RESPONSES_SERVED = 42 - AD_EXCHANGE_REVENUE = 17 - AD_REQUESTS = 38 - AD_SERVER_ACTIVE_VIEW_AVERAGE_VIEWABLE_TIME = 67 - AD_SERVER_ACTIVE_VIEW_ELIGIBLE_IMPRESSIONS = 64 - AD_SERVER_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS = 63 - AD_SERVER_ACTIVE_VIEW_MEASURABLE_IMPRESSIONS_RATE = 66 - AD_SERVER_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS = 62 - AD_SERVER_ACTIVE_VIEW_VIEWABLE_IMPRESSIONS_RATE = 65 - AD_SERVER_AVERAGE_ECPM = 34 - AD_SERVER_AVERAGE_ECPM_WITHOUT_CPD = 10 - AD_SERVER_BEGIN_TO_RENDER_IMPRESSIONS = 262 - AD_SERVER_CLICKS = 7 - AD_SERVER_CPD_REVENUE = 32 - AD_SERVER_CTR = 8 - AD_SERVER_IMPRESSIONS = 6 - AD_SERVER_PERCENT_CLICKS = 12 - AD_SERVER_PERCENT_IMPRESSIONS = 11 - AD_SERVER_PERCENT_REVENUE = 35 - AD_SERVER_PERCENT_REVENUE_WITHOUT_CPD = 13 - AD_SERVER_RESPONSES_SERVED = 40 - AD_SERVER_REVENUE = 33 - AD_SERVER_REVENUE_WITHOUT_CPD = 9 - AD_SERVER_TRACKED_ADS = 264 - AD_SERVER_UNFILTERED_BEGIN_TO_RENDER_IMPRESSIONS = 261 - AD_SERVER_UNFILTERED_CLICKS = 259 - AD_SERVER_UNFILTERED_IMPRESSIONS = 260 - AD_SERVER_UNFILTERED_TRACKED_ADS = 263 - AVERAGE_ECPM = 37 - AVERAGE_ECPM_WITHOUT_CPD = 5 - CLICKS = 2 - CODE_SERVED_COUNT = 44 - CTR = 3 - GOOGLE_SOLD_AUCTION_COVIEWED_IMPRESSIONS = 129 - GOOGLE_SOLD_AUCTION_IMPRESSIONS = 128 - GOOGLE_SOLD_COVIEWED_IMPRESSIONS = 131 - GOOGLE_SOLD_IMPRESSIONS = 130 - GOOGLE_SOLD_RESERVATION_COVIEWED_IMPRESSIONS = 127 - GOOGLE_SOLD_RESERVATION_IMPRESSIONS = 126 - IMPRESSIONS = 1 - PARTNER_SALES_FILLED_POD_REQUESTS = 135 - PARTNER_SALES_FILL_RATE = 136 - PARTNER_SALES_PARTNER_MATCH_RATE = 137 - PARTNER_SALES_QUERIES = 132 - PARTNER_SALES_UNFILLED_IMPRESSIONS = 133 - PARTNER_SALES_UNMATCHED_QUERIES = 134 - PARTNER_SOLD_CODE_SERVED = 125 - PARTNER_SOLD_COVIEWED_IMPRESSIONS = 124 - PARTNER_SOLD_IMPRESSIONS = 123 - PROGRAMMATIC_ELIGIBLE_AD_REQUESTS = 177 - PROGRAMMATIC_MATCH_RATE = 178 - PROGRAMMATIC_RESPONSES_SERVED = 176 - RESPONSES_SERVED = 39 - REVENUE = 36 - REVENUE_WITHOUT_CPD = 4 - SERVER_SIDE_UNWRAPPING_AVERAGE_LATENCY_MS = 434 - SERVER_SIDE_UNWRAPPING_CALLOUTS = 435 - SERVER_SIDE_UNWRAPPING_EMPTY_RESPONSES = 436 - SERVER_SIDE_UNWRAPPING_ERROR_RESPONSES = 437 - SERVER_SIDE_UNWRAPPING_SUCCESSFUL_RESPONSES = 438 - SERVER_SIDE_UNWRAPPING_TIMEOUTS = 439 - UNFILLED_IMPRESSIONS = 45 - UNMATCHED_AD_REQUESTS = 43 - USER_MESSAGES_OFFERWALL_MESSAGES_SHOWN = 121 - USER_MESSAGES_OFFERWALL_SUCCESSFUL_ENGAGEMENTS = 122 - VIDEO_INTERACTION_AVERAGE_INTERACTION_RATE = 92 - VIDEO_INTERACTION_COLLAPSES = 93 - VIDEO_INTERACTION_EXPANDS = 95 - VIDEO_INTERACTION_FULL_SCREENS = 96 - VIDEO_INTERACTION_MUTES = 97 - VIDEO_INTERACTION_PAUSES = 98 - VIDEO_INTERACTION_RESUMES = 99 - VIDEO_INTERACTION_REWINDS = 100 - VIDEO_INTERACTION_UNMUTES = 101 - VIDEO_INTERACTION_VIDEO_SKIPS = 102 - VIDEO_REAL_TIME_CREATIVE_SERVES = 139 - VIDEO_REAL_TIME_ERROR_100_COUNT = 143 - VIDEO_REAL_TIME_ERROR_101_COUNT = 144 - VIDEO_REAL_TIME_ERROR_102_COUNT = 145 - VIDEO_REAL_TIME_ERROR_200_COUNT = 146 - VIDEO_REAL_TIME_ERROR_201_COUNT = 147 - VIDEO_REAL_TIME_ERROR_202_COUNT = 148 - VIDEO_REAL_TIME_ERROR_203_COUNT = 149 - VIDEO_REAL_TIME_ERROR_300_COUNT = 150 - VIDEO_REAL_TIME_ERROR_301_COUNT = 151 - VIDEO_REAL_TIME_ERROR_302_COUNT = 152 - VIDEO_REAL_TIME_ERROR_303_COUNT = 153 - VIDEO_REAL_TIME_ERROR_400_COUNT = 154 - VIDEO_REAL_TIME_ERROR_401_COUNT = 155 - VIDEO_REAL_TIME_ERROR_402_COUNT = 156 - VIDEO_REAL_TIME_ERROR_403_COUNT = 157 - VIDEO_REAL_TIME_ERROR_405_COUNT = 158 - VIDEO_REAL_TIME_ERROR_406_COUNT = 159 - VIDEO_REAL_TIME_ERROR_407_COUNT = 160 - VIDEO_REAL_TIME_ERROR_408_COUNT = 161 - VIDEO_REAL_TIME_ERROR_409_COUNT = 162 - VIDEO_REAL_TIME_ERROR_410_COUNT = 163 - VIDEO_REAL_TIME_ERROR_500_COUNT = 164 - VIDEO_REAL_TIME_ERROR_501_COUNT = 165 - VIDEO_REAL_TIME_ERROR_502_COUNT = 166 - VIDEO_REAL_TIME_ERROR_503_COUNT = 167 - VIDEO_REAL_TIME_ERROR_600_COUNT = 168 - VIDEO_REAL_TIME_ERROR_601_COUNT = 169 - VIDEO_REAL_TIME_ERROR_602_COUNT = 170 - VIDEO_REAL_TIME_ERROR_603_COUNT = 171 - VIDEO_REAL_TIME_ERROR_604_COUNT = 172 - VIDEO_REAL_TIME_ERROR_900_COUNT = 173 - VIDEO_REAL_TIME_ERROR_901_COUNT = 174 - VIDEO_REAL_TIME_IMPRESSIONS = 138 - VIDEO_REAL_TIME_MATCHED_QUERIES = 140 - VIDEO_REAL_TIME_TOTAL_ERROR_COUNT = 175 - VIDEO_REAL_TIME_TOTAL_QUERIES = 142 - VIDEO_REAL_TIME_UNMATCHED_QUERIES = 141 - VIDEO_VIEWERSHIP_AUTO_PLAYS = 103 - VIDEO_VIEWERSHIP_AVERAGE_VIEW_RATE = 104 - VIDEO_VIEWERSHIP_AVERAGE_VIEW_TIME = 105 - VIDEO_VIEWERSHIP_CLICK_TO_PLAYS = 106 - VIDEO_VIEWERSHIP_COMPLETES = 107 - VIDEO_VIEWERSHIP_COMPLETION_RATE = 108 - VIDEO_VIEWERSHIP_ENGAGED_VIEWS = 109 - VIDEO_VIEWERSHIP_FIRST_QUARTILES = 110 - VIDEO_VIEWERSHIP_MIDPOINTS = 111 - VIDEO_VIEWERSHIP_SKIP_BUTTONS_SHOWN = 112 - VIDEO_VIEWERSHIP_STARTS = 113 - VIDEO_VIEWERSHIP_THIRD_QUARTILES = 114 - VIDEO_VIEWERSHIP_TOTAL_ERROR_COUNT = 115 - VIDEO_VIEWERSHIP_TOTAL_ERROR_RATE = 94 - VIDEO_VIEWERSHIP_VIDEO_LENGTH = 116 - VIDEO_VIEWERSHIP_VIEW_THROUGH_RATE = 117 - YIELD_GROUP_AUCTIONS_WON = 80 - YIELD_GROUP_BIDS = 81 - YIELD_GROUP_BIDS_IN_AUCTION = 82 - YIELD_GROUP_CALLOUTS = 83 - YIELD_GROUP_ESTIMATED_CPM = 88 - YIELD_GROUP_ESTIMATED_REVENUE = 87 - YIELD_GROUP_IMPRESSIONS = 85 - YIELD_GROUP_MEDIATION_FILL_RATE = 89 - YIELD_GROUP_MEDIATION_MATCHED_QUERIES = 86 - YIELD_GROUP_MEDIATION_PASSBACKS = 118 - YIELD_GROUP_MEDIATION_THIRD_PARTY_ECPM = 90 - YIELD_GROUP_SUCCESSFUL_RESPONSES = 84 - - class MetricValueType(proto.Enum): - r"""Possible metric value types to add. - - Values: - PRIMARY (0): - The values for the primary date_range. - PRIMARY_PERCENT_OF_TOTAL (1): - Each metrics' percent of the total for the primary - date_range. - COMPARISON (2): - The values for the comparison_date_range. - COMPARISON_PERCENT_OF_TOTAL (3): - Each metrics' percent of the total for the - comparison_date_range. - ABSOLUTE_CHANGE (4): - The absolute change between the primary and - comparison date ranges. - RELATIVE_CHANGE (5): - The relative change between the primary and - comparison date ranges. - """ - PRIMARY = 0 - PRIMARY_PERCENT_OF_TOTAL = 1 - COMPARISON = 2 - COMPARISON_PERCENT_OF_TOTAL = 3 - ABSOLUTE_CHANGE = 4 - RELATIVE_CHANGE = 5 - - class ReportType(proto.Enum): - r"""Supported report types. - - Values: - REPORT_TYPE_UNSPECIFIED (0): - Default value. This value is unused. - HISTORICAL (1): - Historical. - """ - REPORT_TYPE_UNSPECIFIED = 0 - HISTORICAL = 1 - class Visibility(proto.Enum): r"""The visibility of a report. Values: HIDDEN (0): Default value. Reports with hidden visibility - will not appear in the Ad Manager UI. + won't appear in the Ad Manager UI. DRAFT (1): Reports with draft visibility will appear in the Ad Manager UI only if the user has @@ -3444,797 +87,6 @@ class Visibility(proto.Enum): DRAFT = 1 SAVED = 2 - class TimeZoneSource(proto.Enum): - r"""The source to determine the time zone for the report. - - Values: - TIME_ZONE_SOURCE_UNSPECIFIED (0): - Unspecified default value. - PUBLISHER (1): - Use the publisher's time zone in network - settings. - AD_EXCHANGE (2): - Use the time zone of the ad exchange. - Only compatible with Ad Exchange dimensions and - metrics. - UTC (3): - Use UTC time zone. - Only compatible with Revenue Verification - reports. - PROVIDED (4): - Use the time zone provided in the ReportDefinition.time_zone - field. Has limited dimension and metric compatibility - compared with PUBLISHER, and reports may take longer to run - since the dates are dynamically calculated at request time. - """ - TIME_ZONE_SOURCE_UNSPECIFIED = 0 - PUBLISHER = 1 - AD_EXCHANGE = 2 - UTC = 3 - PROVIDED = 4 - - class Value(proto.Message): - r"""Represents a single value in a report. - - 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: - int_value (int): - For integer values. - - This field is a member of `oneof`_ ``value``. - double_value (float): - For double values. - - This field is a member of `oneof`_ ``value``. - string_value (str): - For string values. - - This field is a member of `oneof`_ ``value``. - bool_value (bool): - For boolean values. - - This field is a member of `oneof`_ ``value``. - int_list_value (google.ads.admanager_v1.types.Report.Value.IntList): - For lists of integer values. - - This field is a member of `oneof`_ ``value``. - string_list_value (google.ads.admanager_v1.types.Report.Value.StringList): - For lists of string values. - - This field is a member of `oneof`_ ``value``. - bytes_value (bytes): - For bytes values. - - This field is a member of `oneof`_ ``value``. - """ - - class IntList(proto.Message): - r"""A list of integer values. - - Attributes: - values (MutableSequence[int]): - The values - """ - - values: MutableSequence[int] = proto.RepeatedField( - proto.INT64, - number=1, - ) - - class StringList(proto.Message): - r"""A list of string values. - - Attributes: - values (MutableSequence[str]): - The values - """ - - values: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=1, - ) - - int_value: int = proto.Field( - proto.INT64, - number=1, - oneof="value", - ) - double_value: float = proto.Field( - proto.DOUBLE, - number=2, - oneof="value", - ) - string_value: str = proto.Field( - proto.STRING, - number=3, - oneof="value", - ) - bool_value: bool = proto.Field( - proto.BOOL, - number=4, - oneof="value", - ) - int_list_value: "Report.Value.IntList" = proto.Field( - proto.MESSAGE, - number=6, - oneof="value", - message="Report.Value.IntList", - ) - string_list_value: "Report.Value.StringList" = proto.Field( - proto.MESSAGE, - number=7, - oneof="value", - message="Report.Value.StringList", - ) - bytes_value: bytes = proto.Field( - proto.BYTES, - number=8, - oneof="value", - ) - - class Sort(proto.Message): - r"""Represents a sorting in a report. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - field (google.ads.admanager_v1.types.Report.Field): - Required. A field (dimension or metric) to - sort by. - descending (bool): - Optional. The sort order. If true the sort - will be descending. - slice_ (google.ads.admanager_v1.types.Report.Slice): - Optional. Use to sort on a specific slice of - data. - - This field is a member of `oneof`_ ``_slice``. - time_period_index (int): - Optional. When using time period columns, use - this to sort on a specific column. - - This field is a member of `oneof`_ ``_time_period_index``. - metric_value_type (google.ads.admanager_v1.types.Report.MetricValueType): - Optional. Use to specify which metric value - type to sort on. Defaults to PRIMARY. - - This field is a member of `oneof`_ ``_metric_value_type``. - """ - - field: "Report.Field" = proto.Field( - proto.MESSAGE, - number=1, - message="Report.Field", - ) - descending: bool = proto.Field( - proto.BOOL, - number=2, - ) - slice_: "Report.Slice" = proto.Field( - proto.MESSAGE, - number=3, - optional=True, - message="Report.Slice", - ) - time_period_index: int = proto.Field( - proto.INT32, - number=4, - optional=True, - ) - metric_value_type: "Report.MetricValueType" = proto.Field( - proto.ENUM, - number=5, - optional=True, - enum="Report.MetricValueType", - ) - - class DataTable(proto.Message): - r"""A table containing report data including dimension and metric - values. - - """ - - class Row(proto.Message): - r"""A row of report data. - - Attributes: - dimension_values (MutableSequence[google.ads.admanager_v1.types.Report.Value]): - The order of the dimension values is the same - as the order of the dimensions specified in the - request. - metric_value_groups (MutableSequence[google.ads.admanager_v1.types.Report.DataTable.MetricValueGroup]): - The length of the metric_value_groups field will be equal to - the length of the date_ranges field in the fetch response. - The metric_value_groups field is ordered such that each - index corresponds to the date_range at the same index. For - example, given date_ranges [x, y], metric_value_groups will - have a length of two. The first entry in metric_value_groups - represents the metrics for date x and the second entry in - metric_value_groups represents the metrics for date y. - """ - - dimension_values: MutableSequence["Report.Value"] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message="Report.Value", - ) - metric_value_groups: MutableSequence[ - "Report.DataTable.MetricValueGroup" - ] = proto.RepeatedField( - proto.MESSAGE, - number=2, - message="Report.DataTable.MetricValueGroup", - ) - - class MetricValueGroup(proto.Message): - r"""Contains all metric values requested for a single date range - and set of column dimension values (returned in the columns - field of the response). The order of the metrics in each field - corresponds to the order of the metrics specified in the - request. - - Attributes: - primary_values (MutableSequence[google.ads.admanager_v1.types.Report.Value]): - Data for the PRIMARY MetricValueType. - primary_percent_of_total_values (MutableSequence[google.ads.admanager_v1.types.Report.Value]): - Data for the PRIMARY_PERCENT_OF_TOTAL MetricValueType. - comparison_values (MutableSequence[google.ads.admanager_v1.types.Report.Value]): - Data for the COMPARISON MetricValueType. - comparison_percent_of_total_values (MutableSequence[google.ads.admanager_v1.types.Report.Value]): - Data for the COMPARISON_PERCENT_OF_TOTAL MetricValueType. - absolute_change_values (MutableSequence[google.ads.admanager_v1.types.Report.Value]): - Data for the ABSOLUTE_CHANGE MetricValueType. - relative_change_values (MutableSequence[google.ads.admanager_v1.types.Report.Value]): - Data for the RELATIVE_CHANGE MetricValueType. - flag_values (MutableSequence[bool]): - If true, the flag's conditions are met. If false, the flag's - conditions are not met. flag_values has the same length as - flags and index i of flag_values represents the flag at - index i of flags. - """ - - primary_values: MutableSequence["Report.Value"] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message="Report.Value", - ) - primary_percent_of_total_values: MutableSequence[ - "Report.Value" - ] = proto.RepeatedField( - proto.MESSAGE, - number=2, - message="Report.Value", - ) - comparison_values: MutableSequence["Report.Value"] = proto.RepeatedField( - proto.MESSAGE, - number=3, - message="Report.Value", - ) - comparison_percent_of_total_values: MutableSequence[ - "Report.Value" - ] = proto.RepeatedField( - proto.MESSAGE, - number=4, - message="Report.Value", - ) - absolute_change_values: MutableSequence[ - "Report.Value" - ] = proto.RepeatedField( - proto.MESSAGE, - number=5, - message="Report.Value", - ) - relative_change_values: MutableSequence[ - "Report.Value" - ] = proto.RepeatedField( - proto.MESSAGE, - number=6, - message="Report.Value", - ) - flag_values: MutableSequence[bool] = proto.RepeatedField( - proto.BOOL, - number=7, - ) - - class Field(proto.Message): - r"""A dimension or a metric in a report. - - 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.admanager_v1.types.Report.Dimension): - The dimension this field represents. - - This field is a member of `oneof`_ ``field``. - metric (google.ads.admanager_v1.types.Report.Metric): - The metric this field represents. - - This field is a member of `oneof`_ ``field``. - """ - - dimension: "Report.Dimension" = proto.Field( - proto.ENUM, - number=1, - oneof="field", - enum="Report.Dimension", - ) - metric: "Report.Metric" = proto.Field( - proto.ENUM, - number=2, - oneof="field", - enum="Report.Metric", - ) - - class Slice(proto.Message): - r"""Use to specify a slice of data. - - For example, in a report, to focus on just data from the US, specify - ``COUNTRY_NAME`` for dimension and value: ``"United States"``. - - Attributes: - dimension (google.ads.admanager_v1.types.Report.Dimension): - Required. The dimension to slice on. - value (google.ads.admanager_v1.types.Report.Value): - Required. The value of the dimension. - """ - - dimension: "Report.Dimension" = proto.Field( - proto.ENUM, - number=1, - enum="Report.Dimension", - ) - value: "Report.Value" = proto.Field( - proto.MESSAGE, - number=2, - message="Report.Value", - ) - - class Filter(proto.Message): - r"""A filter over one or more fields. - - 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: - field_filter (google.ads.admanager_v1.types.Report.Filter.FieldFilter): - A filter on a single field. - - This field is a member of `oneof`_ ``type``. - not_filter (google.ads.admanager_v1.types.Report.Filter): - A filter whose result is negated. - - This field is a member of `oneof`_ ``type``. - and_filter (google.ads.admanager_v1.types.Report.Filter.FilterList): - A list of filters whose results are AND-ed. - - This field is a member of `oneof`_ ``type``. - or_filter (google.ads.admanager_v1.types.Report.Filter.FilterList): - A list of filters whose results are OR-ed. - - This field is a member of `oneof`_ ``type``. - """ - - class Operation(proto.Enum): - r"""Supported filter operations. - - Values: - IN (0): - For scalar operands, checks if the operand is - in the set of provided filter values. - - For list operands, checks if any element in the - operand is in the set of provided filter values. - - Default value. - NOT_IN (1): - For scalar operands, checks that the operand - is not in the set of provided filter values. - - For list operands, checks that none of the - elements in the operand is in the set of - provided filter values. - CONTAINS (2): - For scalar string operands, checks if the - operand contains any of the provided filter - substrings. - - For string list operands, checks if any string - in the operand contains any of the provided - filter substrings. - NOT_CONTAINS (3): - For scalar string operands, checks that the - operand contains none of the provided filter - substrings. - - For string list operands, checks that none of - the strings in the operand contain none of the - provided filter substrings. - LESS_THAN (4): - Operand is less than the provided filter - value. - LESS_THAN_EQUALS (5): - Operand is less than or equal to provided - filter value. - GREATER_THAN (6): - Operand is greater than provided filter - value. - GREATER_THAN_EQUALS (7): - Operand is greater than or equal to provided - filter value. - BETWEEN (8): - Operand is between provided filter values. - MATCHES (9): - Operand matches against a regex or set of - regexes (one must match) - NOT_MATCHES (10): - Operand negative matches against a regex or - set of regexes (none must match) - """ - IN = 0 - NOT_IN = 1 - CONTAINS = 2 - NOT_CONTAINS = 3 - LESS_THAN = 4 - LESS_THAN_EQUALS = 5 - GREATER_THAN = 6 - GREATER_THAN_EQUALS = 7 - BETWEEN = 8 - MATCHES = 9 - NOT_MATCHES = 10 - - class FieldFilter(proto.Message): - r"""A filter on a specific field. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - field (google.ads.admanager_v1.types.Report.Field): - Required. The field to filter on. - operation (google.ads.admanager_v1.types.Report.Filter.Operation): - Required. The operation of this filter. - values (MutableSequence[google.ads.admanager_v1.types.Report.Value]): - Required. Values to filter to. - slice_ (google.ads.admanager_v1.types.Report.Slice): - Optional. Use to filter on a specific slice - of data. - - This field is a member of `oneof`_ ``_slice``. - time_period_index (int): - Optional. When using time period columns, use - this to filter on a specific column. - - This field is a member of `oneof`_ ``_time_period_index``. - metric_value_type (google.ads.admanager_v1.types.Report.MetricValueType): - Optional. Use to specify which metric value - type to filter on. Defaults to PRIMARY. - - This field is a member of `oneof`_ ``_metric_value_type``. - """ - - field: "Report.Field" = proto.Field( - proto.MESSAGE, - number=1, - message="Report.Field", - ) - operation: "Report.Filter.Operation" = proto.Field( - proto.ENUM, - number=2, - enum="Report.Filter.Operation", - ) - values: MutableSequence["Report.Value"] = proto.RepeatedField( - proto.MESSAGE, - number=3, - message="Report.Value", - ) - slice_: "Report.Slice" = proto.Field( - proto.MESSAGE, - number=4, - optional=True, - message="Report.Slice", - ) - time_period_index: int = proto.Field( - proto.INT32, - number=5, - optional=True, - ) - metric_value_type: "Report.MetricValueType" = proto.Field( - proto.ENUM, - number=6, - optional=True, - enum="Report.MetricValueType", - ) - - class FilterList(proto.Message): - r"""A list of filters. - - Attributes: - filters (MutableSequence[google.ads.admanager_v1.types.Report.Filter]): - Required. A list of filters. - """ - - filters: MutableSequence["Report.Filter"] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message="Report.Filter", - ) - - field_filter: "Report.Filter.FieldFilter" = proto.Field( - proto.MESSAGE, - number=1, - oneof="type", - message="Report.Filter.FieldFilter", - ) - not_filter: "Report.Filter" = proto.Field( - proto.MESSAGE, - number=2, - oneof="type", - message="Report.Filter", - ) - and_filter: "Report.Filter.FilterList" = proto.Field( - proto.MESSAGE, - number=3, - oneof="type", - message="Report.Filter.FilterList", - ) - or_filter: "Report.Filter.FilterList" = proto.Field( - proto.MESSAGE, - number=4, - oneof="type", - message="Report.Filter.FilterList", - ) - - class Flag(proto.Message): - r"""A flag for a report. Flags are used show if certain thresholds are - met. Result rows that match the filter will have the corresponding - [MetricValueGroup.flagValues][MetricValueGroup] index set to true. - For more information about flags see: - https://support.google.com/admanager/answer/15079975 - - Attributes: - filters (MutableSequence[google.ads.admanager_v1.types.Report.Filter]): - Required. Filters to apply for the flag. - name (str): - Optional. Name of the flag. - The flag names RED, YELLOW, GREEN, BLUE, PURPLE, - and GREY correspond to the colored flags that - appear in the UI. The UI will not display flags - with other names, but they are available for use - by API clients. - """ - - filters: MutableSequence["Report.Filter"] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message="Report.Filter", - ) - name: str = proto.Field( - proto.STRING, - number=2, - ) - - class DateRange(proto.Message): - r"""A date range for a report. - - 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: - fixed (google.ads.admanager_v1.types.Report.DateRange.FixedDateRange): - A fixed date range. - - This field is a member of `oneof`_ ``date_range_type``. - relative (google.ads.admanager_v1.types.Report.DateRange.RelativeDateRange): - A relative date range. - - This field is a member of `oneof`_ ``date_range_type``. - """ - - class RelativeDateRange(proto.Enum): - r"""Options for relative date ranges. - - Values: - RELATIVE_DATE_RANGE_UNSPECIFIED (0): - Default value. This value is unused. - TODAY (1): - The date the report is run. - YESTERDAY (2): - The date a day before the date that the - report is run. - THIS_WEEK (3): - The full week in which this report is run. - Could include dates in the future. - THIS_WEEK_TO_DATE (29): - From the beginning of the calendar week - (Monday to Sunday) in which the up to and - including the day the report is run. - THIS_MONTH (4): - The full month in which this report is run. - Could include dates in the future. - THIS_MONTH_TO_DATE (26): - From the beginning of the calendar month in - which the report is run, to up to and including - the day the report is run. - THIS_QUARTER (5): - The full quarter in which this report is run. - Could include dates in the future. - THIS_QUARTER_TO_DATE (27): - From the beginning of the calendar quarter in - which the report is run, up to and including the - day the report is run. - THIS_YEAR (6): - The full year in which this report is run. - Could include dates in the future. - THIS_YEAR_TO_DATE (28): - From the beginning of the calendar year in - which the report is run, to up to and including - the day the report is run. - LAST_WEEK (7): - The entire previous calendar week, Monday to - Sunday (inclusive), preceding the calendar week - the report is run. - LAST_MONTH (8): - The entire previous calendar month preceding - the calendar month the report is run. - LAST_QUARTER (9): - The entire previous calendar quarter - preceding the calendar quarter the report is - run. - LAST_YEAR (10): - The entire previous calendar year preceding - the calendar year the report is run. - LAST_7_DAYS (11): - The 7 days preceding the day the report is - run. - LAST_30_DAYS (12): - The 30 days preceding the day the report is - run. - LAST_60_DAYS (13): - The 60 days preceding the day the report is - run. - LAST_90_DAYS (14): - The 90 days preceding the day the report is - run. - LAST_180_DAYS (15): - The 180 days preceding the day the report is - run. - LAST_360_DAYS (16): - The 360 days preceding the day the report is - run. - LAST_365_DAYS (17): - The 365 days preceding the day the report is - run. - LAST_3_MONTHS (18): - The entire previous 3 calendar months - preceding the calendar month the report is run. - LAST_6_MONTHS (19): - The entire previous 6 calendar months - preceding the calendar month the report is run. - LAST_12_MONTHS (20): - The entire previous 6 calendar months - preceding the calendar month the report is run. - ALL_AVAILABLE (21): - From 3 years before the report is run, to the - day before the report is run, inclusive. - PREVIOUS_PERIOD (22): - Only valid when used in the comparison_date_range field. The - complete period preceding the date period provided in - date_range. - - In the case where date_range is a FixedDateRange of N days, - this will be a period of N days where the end date is the - date preceding the start date of the date_range. - - In the case where date_range is a RelativeDateRange, this - will be a period of the same time frame preceding the - date_range. In the case where the date_range does not - capture the full period because a report is run in the - middle of that period, this will still be the full preceding - period. For example, if date_range is THIS_WEEK, but the - report is run on a Wednesday, THIS_WEEK will be Monday - - Wednesday, but PREVIOUS_PERIOD will be Monday - Sunday. - SAME_PERIOD_PREVIOUS_YEAR (24): - Only valid when used in the comparison_date_range field. The - period starting 1 year prior to the date period provided in - date_range. - - In the case where date_range is a FixedDateRange, this will - be a date range starting 1 year prior to the date_range - start date and ending 1 year prior to the date_range end - date. - - In the case where date_range is a RelativeDateRange, this - will be a period of the same time frame exactly 1 year prior - to the date_range. In the case where the date_range does not - capture the full period because a report is run in the - middle of that period, this will still be the full period 1 - year prior. For example, if date range is THIS_WEEK, but the - report is run on a Wednesday, THIS_WEEK will be Monday - - Wednesday, but SAME_PERIOD_PREVIOUS_YEAR will be Monday - - Sunday. - """ - RELATIVE_DATE_RANGE_UNSPECIFIED = 0 - TODAY = 1 - YESTERDAY = 2 - THIS_WEEK = 3 - THIS_WEEK_TO_DATE = 29 - THIS_MONTH = 4 - THIS_MONTH_TO_DATE = 26 - THIS_QUARTER = 5 - THIS_QUARTER_TO_DATE = 27 - THIS_YEAR = 6 - THIS_YEAR_TO_DATE = 28 - LAST_WEEK = 7 - LAST_MONTH = 8 - LAST_QUARTER = 9 - LAST_YEAR = 10 - LAST_7_DAYS = 11 - LAST_30_DAYS = 12 - LAST_60_DAYS = 13 - LAST_90_DAYS = 14 - LAST_180_DAYS = 15 - LAST_360_DAYS = 16 - LAST_365_DAYS = 17 - LAST_3_MONTHS = 18 - LAST_6_MONTHS = 19 - LAST_12_MONTHS = 20 - ALL_AVAILABLE = 21 - PREVIOUS_PERIOD = 22 - SAME_PERIOD_PREVIOUS_YEAR = 24 - - class FixedDateRange(proto.Message): - r"""A date range between two fixed dates (inclusive of end date). - - Attributes: - start_date (google.type.date_pb2.Date): - Required. The start date of this date range. - end_date (google.type.date_pb2.Date): - Required. The end date (inclusive) of this - date range. - """ - - start_date: date_pb2.Date = proto.Field( - proto.MESSAGE, - number=1, - message=date_pb2.Date, - ) - end_date: date_pb2.Date = proto.Field( - proto.MESSAGE, - number=2, - message=date_pb2.Date, - ) - - fixed: "Report.DateRange.FixedDateRange" = proto.Field( - proto.MESSAGE, - number=1, - oneof="date_range_type", - message="Report.DateRange.FixedDateRange", - ) - relative: "Report.DateRange.RelativeDateRange" = proto.Field( - proto.ENUM, - number=2, - oneof="date_range_type", - enum="Report.DateRange.RelativeDateRange", - ) - name: str = proto.Field( proto.STRING, number=1, @@ -4248,10 +100,10 @@ class FixedDateRange(proto.Message): number=2, enum=Visibility, ) - report_definition: "ReportDefinition" = proto.Field( + report_definition: gaa_report_definition.ReportDefinition = proto.Field( proto.MESSAGE, number=4, - message="ReportDefinition", + message=gaa_report_definition.ReportDefinition, ) display_name: str = proto.Field( proto.STRING, @@ -4278,177 +130,129 @@ class FixedDateRange(proto.Message): ) -class ReportDefinition(proto.Message): - r"""The definition of how a report should be run. +class ReportDataTable(proto.Message): + r"""A table containing report data including dimension and metric + values. - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + """ - Attributes: - dimensions (MutableSequence[google.ads.admanager_v1.types.Report.Dimension]): - Required. The list of dimensions to report - on. If empty, the report will have no - dimensions, and any metrics will be totals. - metrics (MutableSequence[google.ads.admanager_v1.types.Report.Metric]): - Required. The list of metrics to report on. - If empty, the report will have no metrics. - filters (MutableSequence[google.ads.admanager_v1.types.Report.Filter]): - Optional. The filters for this report. - time_zone_source (google.ads.admanager_v1.types.Report.TimeZoneSource): - Optional. Where to get the time zone for this report. - Defaults to using the network time zone setting (PUBLISHER). - If source is PROVIDED, the time_zone field in the report - definition must also be provided with the desired time zone. - time_zone (str): - Optional. If time_zone_source is PROVIDED, this is the time - zone to use for this report. Leave empty for any other time - zone source. Time zone in IANA format (e.g. - "America/New_York"). - currency_code (str): - Optional. The ISO 4217 currency code for this - report. Defaults to publisher currency code if - not specified. - date_range (google.ads.admanager_v1.types.Report.DateRange): - Required. The primary date range of this - report. - comparison_date_range (google.ads.admanager_v1.types.Report.DateRange): - Optional. The comparison date range of this - report. If unspecified, the report will not have - any comparison metrics. + class Row(proto.Message): + r"""A row of report data. - This field is a member of `oneof`_ ``_comparison_date_range``. - custom_dimension_key_ids (MutableSequence[int]): - Optional. Custom Dimension keys that represent - CUSTOM_DIMENSION\_\* dimensions. The index of this repeated - field corresponds to the index on each dimension. For - example, custom_dimension_key_ids[0] describes - CUSTOM_DIMENSION_0_VALUE_ID and CUSTOM_DIMENSION_0_VALUE. - line_item_custom_field_ids (MutableSequence[int]): - Optional. Custom field IDs that represent - LINE_ITEM_CUSTOM_FIELD\_\* dimensions. The index of this - repeated field corresponds to the index on each dimension. - For example, line_item_custom_field_ids[0] describes - LINE_ITEM_CUSTOM_FIELD_0_OPTION_ID and - LINE_ITEM_CUSTOM_FIELD_0_VALUE. - order_custom_field_ids (MutableSequence[int]): - Optional. Custom field IDs that represent - ORDER_CUSTOM_FIELD\_\* dimensions. The index of this - repeated field corresponds to the index on each dimension. - For example, order_custom_field_ids[0] describes - ORDER_CUSTOM_FIELD_0_OPTION_ID and - ORDER_CUSTOM_FIELD_0_VALUE. - creative_custom_field_ids (MutableSequence[int]): - Optional. Custom field IDs that represent - CREATIVE_CUSTOM_FIELD\_\* dimensions. The index of this - repeated field corresponds to the index on each dimension. - For example, creative_custom_field_ids[0] describes - CREATIVE_CUSTOM_FIELD_0_OPTION_ID and - CREATIVE_CUSTOM_FIELD_0_VALUE. - report_type (google.ads.admanager_v1.types.Report.ReportType): - Required. The type of this report. - time_period_column (google.ads.admanager_v1.types.Report.TimePeriodColumn): - Optional. Include a time period column to introduce - comparison columns in the report for each generated period. - For example, set to "QUARTERS" here to have a column for - each quarter present in the primary date range. If "PREVIOUS - PERIOD" is specified in comparison_date_range, then each - quarter column will also include comparison values for its - relative previous quarter. - flags (MutableSequence[google.ads.admanager_v1.types.Report.Flag]): - Optional. List of flags for this report. Used - to flag rows in a result set based on a set of - defined filters. - sorts (MutableSequence[google.ads.admanager_v1.types.Report.Sort]): - Optional. Default sorts to apply to this - report. - """ + Attributes: + dimension_values (MutableSequence[google.ads.admanager_v1.types.ReportValue]): + The order of the dimension values is the same + as the order of the dimensions specified in the + request. + metric_value_groups (MutableSequence[google.ads.admanager_v1.types.ReportDataTable.MetricValueGroup]): + The length of the metric_value_groups field will be equal to + the length of the date_ranges field in the fetch response. + The metric_value_groups field is ordered such that each + index corresponds to the date_range at the same index. For + example, given date_ranges [x, y], metric_value_groups will + have a length of two. The first entry in metric_value_groups + represents the metrics for date x and the second entry in + metric_value_groups represents the metrics for date y. + """ - dimensions: MutableSequence["Report.Dimension"] = proto.RepeatedField( - proto.ENUM, - number=1, - enum="Report.Dimension", - ) - metrics: MutableSequence["Report.Metric"] = proto.RepeatedField( - proto.ENUM, - number=2, - enum="Report.Metric", - ) - filters: MutableSequence["Report.Filter"] = proto.RepeatedField( - proto.MESSAGE, - number=3, - message="Report.Filter", - ) - time_zone_source: "Report.TimeZoneSource" = proto.Field( - proto.ENUM, - number=20, - enum="Report.TimeZoneSource", - ) - time_zone: str = proto.Field( - proto.STRING, - number=4, - ) - currency_code: str = proto.Field( - proto.STRING, - number=5, - ) - date_range: "Report.DateRange" = proto.Field( - proto.MESSAGE, - number=6, - message="Report.DateRange", - ) - comparison_date_range: "Report.DateRange" = proto.Field( - proto.MESSAGE, - number=9, - optional=True, - message="Report.DateRange", - ) - custom_dimension_key_ids: MutableSequence[int] = proto.RepeatedField( - proto.INT64, - number=7, - ) - line_item_custom_field_ids: MutableSequence[int] = proto.RepeatedField( - proto.INT64, - number=11, - ) - order_custom_field_ids: MutableSequence[int] = proto.RepeatedField( - proto.INT64, - number=12, - ) - creative_custom_field_ids: MutableSequence[int] = proto.RepeatedField( - proto.INT64, - number=13, - ) - report_type: "Report.ReportType" = proto.Field( - proto.ENUM, - number=8, - enum="Report.ReportType", - ) - time_period_column: "Report.TimePeriodColumn" = proto.Field( - proto.ENUM, - number=10, - enum="Report.TimePeriodColumn", - ) - flags: MutableSequence["Report.Flag"] = proto.RepeatedField( - proto.MESSAGE, - number=14, - message="Report.Flag", - ) - sorts: MutableSequence["Report.Sort"] = proto.RepeatedField( - proto.MESSAGE, - number=15, - message="Report.Sort", - ) + dimension_values: MutableSequence[ + report_value.ReportValue + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=report_value.ReportValue, + ) + metric_value_groups: MutableSequence[ + "ReportDataTable.MetricValueGroup" + ] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="ReportDataTable.MetricValueGroup", + ) + + class MetricValueGroup(proto.Message): + r"""Contains all metric values requested for a single date range + and set of column dimension values (returned in the columns + field of the response). The order of the metrics in each field + corresponds to the order of the metrics specified in the + request. + + Attributes: + primary_values (MutableSequence[google.ads.admanager_v1.types.ReportValue]): + Data for the PRIMARY MetricValueType. + primary_percent_of_total_values (MutableSequence[google.ads.admanager_v1.types.ReportValue]): + Data for the PRIMARY_PERCENT_OF_TOTAL MetricValueType. + comparison_values (MutableSequence[google.ads.admanager_v1.types.ReportValue]): + Data for the COMPARISON MetricValueType. + comparison_percent_of_total_values (MutableSequence[google.ads.admanager_v1.types.ReportValue]): + Data for the COMPARISON_PERCENT_OF_TOTAL MetricValueType. + absolute_change_values (MutableSequence[google.ads.admanager_v1.types.ReportValue]): + Data for the ABSOLUTE_CHANGE MetricValueType. + relative_change_values (MutableSequence[google.ads.admanager_v1.types.ReportValue]): + Data for the RELATIVE_CHANGE MetricValueType. + flag_values (MutableSequence[bool]): + If true, the flag's conditions are met. If false, the flag's + conditions are not met. flag_values has the same length as + flags and index i of flag_values represents the flag at + index i of flags. + """ + + primary_values: MutableSequence[report_value.ReportValue] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=report_value.ReportValue, + ) + primary_percent_of_total_values: MutableSequence[ + report_value.ReportValue + ] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=report_value.ReportValue, + ) + comparison_values: MutableSequence[ + report_value.ReportValue + ] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=report_value.ReportValue, + ) + comparison_percent_of_total_values: MutableSequence[ + report_value.ReportValue + ] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=report_value.ReportValue, + ) + absolute_change_values: MutableSequence[ + report_value.ReportValue + ] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message=report_value.ReportValue, + ) + relative_change_values: MutableSequence[ + report_value.ReportValue + ] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message=report_value.ReportValue, + ) + flag_values: MutableSequence[bool] = proto.RepeatedField( + proto.BOOL, + number=7, + ) class ScheduleOptions(proto.Message): r"""The options for a scheduled report. Attributes: - schedule (google.ads.admanager_v1.types.Schedule): + schedule (google.ads.admanager_v1.types.ScheduleOptions.Schedule): Information pertaining to schedule itself. delivery_condition (google.ads.admanager_v1.types.ScheduleOptions.DeliveryCondition): Option for when to deliver the scheduled report. - flags (MutableSequence[google.ads.admanager_v1.types.Report.Flag]): + flags (MutableSequence[google.ads.admanager_v1.types.ReportDefinition.Flag]): Optional. The flags evaluated when ReportDeliveryOption.WHEN_FLAG_PRESENT is specified. """ @@ -4469,158 +273,159 @@ class DeliveryCondition(proto.Enum): ALWAYS = 1 WHEN_FLAG_CONDITIONS_MET = 2 - schedule: "Schedule" = proto.Field( - proto.MESSAGE, - number=1, - message="Schedule", - ) - delivery_condition: DeliveryCondition = proto.Field( - proto.ENUM, - number=2, - enum=DeliveryCondition, - ) - flags: MutableSequence["Report.Flag"] = proto.RepeatedField( - proto.MESSAGE, - number=3, - message="Report.Flag", - ) - + class Schedule(proto.Message): + r"""The schedule for the report -class Schedule(proto.Message): - r"""The schedule for the report - - 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. + 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 + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - Attributes: - weekly_schedule (google.ads.admanager_v1.types.Schedule.WeeklySchedule): - Days of week to schedule report run. + Attributes: + weekly_schedule (google.ads.admanager_v1.types.ScheduleOptions.Schedule.WeeklySchedule): + Days of week to schedule report run. + + This field is a member of `oneof`_ ``frequency_schedule``. + monthly_schedule (google.ads.admanager_v1.types.ScheduleOptions.Schedule.MonthlySchedule): + Days of month to schedule report run. + + This field is a member of `oneof`_ ``frequency_schedule``. + start_date (google.type.date_pb2.Date): + Date for the first run of the report. + end_date (google.type.date_pb2.Date): + Date for the final run of the report. + frequency (google.ads.admanager_v1.types.ScheduleOptions.Schedule.Frequency): + Frequency to run report. + start_time (google.type.timeofday_pb2.TimeOfDay): + Indicates start time for schedule to run Will use the + time_zone from ``ReportDefinition``. Defaults to the + publisher's time zone if not specified. + + For HOURLY, TWO_TIMES_DAILY, THREE_TIMES_DAILY, or + FOUR_TIMES_DAILY, this will be the time of day that the + first report will run on the first day. For example, if the + start time is 2:00 PM, and the frequency is + THREE_TIMES_DAILY, the first day will have reports scheduled + at 2:00 PM, 10:00 PM. Each subsequent day will have reports + scheduled at 6:00 AM, 2:00 PM, 10:00 PM. + """ - This field is a member of `oneof`_ ``frequency_schedule``. - monthly_schedule (google.ads.admanager_v1.types.Schedule.MonthlySchedule): - Days of month to schedule report run. + class Frequency(proto.Enum): + r"""Frequency to run report. - This field is a member of `oneof`_ ``frequency_schedule``. - start_date (google.type.date_pb2.Date): - Date for the first run of the report. - end_date (google.type.date_pb2.Date): - Date for the final run of the report. - frequency (google.ads.admanager_v1.types.Schedule.Frequency): - Frequency to run report. - start_time (google.type.timeofday_pb2.TimeOfDay): - Indicates start time for schedule to run Will use the - time_zone from ``ReportDefinition``. Defaults to the - publisher's time zone if not specified. + Values: + FREQUENCY_UNSPECIFIED (0): + No Frequency specified. + HOURLY (1): + Schedule report to run every hour. + TWO_TIMES_DAILY (2): + Schedule report to run twice a day (every 12 + hours). + THREE_TIMES_DAILY (3): + Schedule report to run three times a day + (every 8 hours). + FOUR_TIMES_DAILY (4): + Schedule report to run four times a day + (every 6 hours). + DAILY (5): + Schedule report to run on a daily basis. + WEEKLY (6): + Schedule report to run on a weekly basis. + MONTHLY (7): + Schedule report to run on a monthly basis. + """ + FREQUENCY_UNSPECIFIED = 0 + HOURLY = 1 + TWO_TIMES_DAILY = 2 + THREE_TIMES_DAILY = 3 + FOUR_TIMES_DAILY = 4 + DAILY = 5 + WEEKLY = 6 + MONTHLY = 7 + + class WeeklySchedule(proto.Message): + r"""Days of week to schedule report run. - For HOURLY, TWO_TIMES_DAILY, THREE_TIMES_DAILY, or - FOUR_TIMES_DAILY, this will be the time of day that the - first report will run on the first day. For example, if the - start time is 2:00 PM, and the frequency is - THREE_TIMES_DAILY, the first day will have reports scheduled - at 2:00 PM, 10:00 PM. Each subsequent day will have reports - scheduled at 6:00 AM, 2:00 PM, 10:00 PM. - """ + Attributes: + weekly_scheduled_days (MutableSequence[google.type.dayofweek_pb2.DayOfWeek]): + Specifies days of the week on which to run + report. + """ - class Frequency(proto.Enum): - r"""Frequency to run report. + weekly_scheduled_days: MutableSequence[ + dayofweek_pb2.DayOfWeek + ] = proto.RepeatedField( + proto.ENUM, + number=1, + enum=dayofweek_pb2.DayOfWeek, + ) - Values: - FREQUENCY_UNSPECIFIED (0): - No Frequency specified. - HOURLY (1): - Schedule report to run every hour. - TWO_TIMES_DAILY (2): - Schedule report to run twice a day (every 12 - hours). - THREE_TIMES_DAILY (3): - Schedule report to run three times a day - (every 8 hours). - FOUR_TIMES_DAILY (4): - Schedule report to run four times a day - (every 6 hours). - DAILY (5): - Schedule report to run on a daily basis. - WEEKLY (6): - Schedule report to run on a weekly basis. - MONTHLY (7): - Schedule report to run on a monthly basis. - """ - FREQUENCY_UNSPECIFIED = 0 - HOURLY = 1 - TWO_TIMES_DAILY = 2 - THREE_TIMES_DAILY = 3 - FOUR_TIMES_DAILY = 4 - DAILY = 5 - WEEKLY = 6 - MONTHLY = 7 + class MonthlySchedule(proto.Message): + r"""Days of Month to schedule report run. - class WeeklySchedule(proto.Message): - r"""Days of week to schedule report run. + Attributes: + monthly_scheduled_days (MutableSequence[int]): + Specifies days of the month to run report. + Range is from 1-31. Will ignore days that are + not valid for the given month. + """ - Attributes: - weekly_scheduled_days (MutableSequence[google.type.dayofweek_pb2.DayOfWeek]): - Specifies days of the week on which to run - report. - """ + monthly_scheduled_days: MutableSequence[int] = proto.RepeatedField( + proto.INT32, + number=1, + ) - weekly_scheduled_days: MutableSequence[ - dayofweek_pb2.DayOfWeek - ] = proto.RepeatedField( - proto.ENUM, - number=1, - enum=dayofweek_pb2.DayOfWeek, + weekly_schedule: "ScheduleOptions.Schedule.WeeklySchedule" = proto.Field( + proto.MESSAGE, + number=6, + oneof="frequency_schedule", + message="ScheduleOptions.Schedule.WeeklySchedule", ) - - class MonthlySchedule(proto.Message): - r"""Days of Month to schedule report run. - - Attributes: - monthly_scheduled_days (MutableSequence[int]): - Specifies days of the month to run report. - Range is from 1-31. Will ignore days that are - not valid for the given month. - """ - - monthly_scheduled_days: MutableSequence[int] = proto.RepeatedField( - proto.INT32, + monthly_schedule: "ScheduleOptions.Schedule.MonthlySchedule" = proto.Field( + proto.MESSAGE, + number=7, + oneof="frequency_schedule", + message="ScheduleOptions.Schedule.MonthlySchedule", + ) + start_date: date_pb2.Date = proto.Field( + proto.MESSAGE, number=1, + message=date_pb2.Date, + ) + end_date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=2, + message=date_pb2.Date, + ) + frequency: "ScheduleOptions.Schedule.Frequency" = proto.Field( + proto.ENUM, + number=3, + enum="ScheduleOptions.Schedule.Frequency", + ) + start_time: timeofday_pb2.TimeOfDay = proto.Field( + proto.MESSAGE, + number=4, + message=timeofday_pb2.TimeOfDay, ) - weekly_schedule: WeeklySchedule = proto.Field( - proto.MESSAGE, - number=6, - oneof="frequency_schedule", - message=WeeklySchedule, - ) - monthly_schedule: MonthlySchedule = proto.Field( - proto.MESSAGE, - number=7, - oneof="frequency_schedule", - message=MonthlySchedule, - ) - start_date: date_pb2.Date = proto.Field( + schedule: Schedule = proto.Field( proto.MESSAGE, number=1, - message=date_pb2.Date, - ) - end_date: date_pb2.Date = proto.Field( - proto.MESSAGE, - number=2, - message=date_pb2.Date, + message=Schedule, ) - frequency: Frequency = proto.Field( + delivery_condition: DeliveryCondition = proto.Field( proto.ENUM, - number=3, - enum=Frequency, + number=2, + enum=DeliveryCondition, ) - start_time: timeofday_pb2.TimeOfDay = proto.Field( + flags: MutableSequence[ + gaa_report_definition.ReportDefinition.Flag + ] = proto.RepeatedField( proto.MESSAGE, - number=4, - message=timeofday_pb2.TimeOfDay, + number=3, + message=gaa_report_definition.ReportDefinition.Flag, ) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/report_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/report_service.py index c0bcace43e5e..61767f61bf4f 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/report_service.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/report_service.py @@ -21,7 +21,7 @@ from google.protobuf import timestamp_pb2 # type: ignore import proto # type: ignore -from google.ads.admanager_v1.types import report_messages +from google.ads.admanager_v1.types import report_definition, report_messages __protobuf__ = proto.module( package="google.ads.admanager.v1", @@ -118,7 +118,7 @@ class ListReportsRequest(proto.Message): Optional. The maximum number of ``Reports`` to return. The service may return fewer than this value. If unspecified, at most 50 ``Reports`` will be returned. The maximum value is - 1000; values above 1000 will be coerced to 1000. + 1000; values greater than 1000 will be coerced to 1000. page_token (str): Optional. A page token, received from a previous ``ListReports`` call. Provide this to retrieve the @@ -182,8 +182,8 @@ class ListReportsResponse(proto.Message): in the request, this reflects the total number after the filtering is applied. - ``total_size`` will not be calculated in the response unless - it has been included in a response field mask. The response + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response field mask can be provided to the method by using the URL parameter ``$fields`` or ``fields``, or by using the HTTP/gRPC header ``X-Goog-FieldMask``. @@ -268,7 +268,7 @@ class FetchReportResultRowsRequest(proto.Message): return. The service may return fewer than this value. If unspecified, at most 1,000 rows will be returned. The maximum value is 10,000; values - above 10,000 will be reduced to 10,000. + greater than 10,000 will be reduced to 10,000. page_token (str): Optional. A page token, received from a previous ``FetchReportResultRows`` call. Provide this to retrieve the @@ -294,17 +294,17 @@ class FetchReportResultRowsResponse(proto.Message): endpoint. Attributes: - rows (MutableSequence[google.ads.admanager_v1.types.Report.DataTable.Row]): + rows (MutableSequence[google.ads.admanager_v1.types.ReportDataTable.Row]): Up to ``page_size`` rows of report data. run_time (google.protobuf.timestamp_pb2.Timestamp): The time at which the report was scheduled to run. For non-scheduled reports, this is the time at which the report was requested to be run. - date_ranges (MutableSequence[google.ads.admanager_v1.types.Report.DateRange.FixedDateRange]): + date_ranges (MutableSequence[google.ads.admanager_v1.types.ReportDefinition.DateRange.FixedDateRange]): The computed fixed date ranges this report includes. Only returned with the first page of results (when page_token is not included in the request). - comparison_date_ranges (MutableSequence[google.ads.admanager_v1.types.Report.DateRange.FixedDateRange]): + comparison_date_ranges (MutableSequence[google.ads.admanager_v1.types.ReportDefinition.DateRange.FixedDateRange]): The computed comparison fixed date ranges this report includes. Only returned with the first page of results (when page_token is not included in the request). @@ -322,10 +322,10 @@ class FetchReportResultRowsResponse(proto.Message): def raw_page(self): return self - rows: MutableSequence[report_messages.Report.DataTable.Row] = proto.RepeatedField( + rows: MutableSequence[report_messages.ReportDataTable.Row] = proto.RepeatedField( proto.MESSAGE, number=1, - message=report_messages.Report.DataTable.Row, + message=report_messages.ReportDataTable.Row, ) run_time: timestamp_pb2.Timestamp = proto.Field( proto.MESSAGE, @@ -333,18 +333,18 @@ def raw_page(self): message=timestamp_pb2.Timestamp, ) date_ranges: MutableSequence[ - report_messages.Report.DateRange.FixedDateRange + report_definition.ReportDefinition.DateRange.FixedDateRange ] = proto.RepeatedField( proto.MESSAGE, number=3, - message=report_messages.Report.DateRange.FixedDateRange, + message=report_definition.ReportDefinition.DateRange.FixedDateRange, ) comparison_date_ranges: MutableSequence[ - report_messages.Report.DateRange.FixedDateRange + report_definition.ReportDefinition.DateRange.FixedDateRange ] = proto.RepeatedField( proto.MESSAGE, number=4, - message=report_messages.Report.DateRange.FixedDateRange, + message=report_definition.ReportDefinition.DateRange.FixedDateRange, ) total_row_count: int = proto.Field( proto.INT32, diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/report_value.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/report_value.py new file mode 100644 index 000000000000..bbeac7f76f09 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/report_value.py @@ -0,0 +1,159 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "ReportValue", + }, +) + + +class ReportValue(proto.Message): + r"""Represents a single value in a report. + + 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: + int_value (int): + For integer values. + + This field is a member of `oneof`_ ``value``. + double_value (float): + For double values. + + This field is a member of `oneof`_ ``value``. + string_value (str): + For string values. + + This field is a member of `oneof`_ ``value``. + bool_value (bool): + For boolean values. + + This field is a member of `oneof`_ ``value``. + int_list_value (google.ads.admanager_v1.types.ReportValue.IntList): + For lists of integer values. + + This field is a member of `oneof`_ ``value``. + string_list_value (google.ads.admanager_v1.types.ReportValue.StringList): + For lists of string values. + + This field is a member of `oneof`_ ``value``. + double_list_value (google.ads.admanager_v1.types.ReportValue.DoubleList): + For lists of double values. + + This field is a member of `oneof`_ ``value``. + bytes_value (bytes): + For bytes values. + + This field is a member of `oneof`_ ``value``. + """ + + class IntList(proto.Message): + r"""A list of integer values. + + Attributes: + values (MutableSequence[int]): + The values + """ + + values: MutableSequence[int] = proto.RepeatedField( + proto.INT64, + number=1, + ) + + class StringList(proto.Message): + r"""A list of string values. + + Attributes: + values (MutableSequence[str]): + The values + """ + + values: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + class DoubleList(proto.Message): + r"""A list of double values. + + Attributes: + values (MutableSequence[float]): + The values + """ + + values: MutableSequence[float] = proto.RepeatedField( + proto.DOUBLE, + number=1, + ) + + int_value: int = proto.Field( + proto.INT64, + number=1, + oneof="value", + ) + double_value: float = proto.Field( + proto.DOUBLE, + number=2, + oneof="value", + ) + string_value: str = proto.Field( + proto.STRING, + number=3, + oneof="value", + ) + bool_value: bool = proto.Field( + proto.BOOL, + number=4, + oneof="value", + ) + int_list_value: IntList = proto.Field( + proto.MESSAGE, + number=6, + oneof="value", + message=IntList, + ) + string_list_value: StringList = proto.Field( + proto.MESSAGE, + number=7, + oneof="value", + message=StringList, + ) + double_list_value: DoubleList = proto.Field( + proto.MESSAGE, + number=9, + oneof="value", + message=DoubleList, + ) + bytes_value: bytes = proto.Field( + proto.BYTES, + number=8, + oneof="value", + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/role_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/role_service.py index 58f85aaee54b..47230fcb8677 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/role_service.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/role_service.py @@ -57,7 +57,7 @@ class ListRolesRequest(proto.Message): Optional. The maximum number of ``Roles`` to return. The service may return fewer than this value. If unspecified, at most 50 ``Roles`` will be returned. The maximum value is - 1000; values above 1000 will be coerced to 1000. + 1000; values greater than 1000 will be coerced to 1000. page_token (str): Optional. A page token, received from a previous ``ListRoles`` call. Provide this to retrieve the subsequent @@ -121,8 +121,8 @@ class ListRolesResponse(proto.Message): in the request, this reflects the total number after the filtering is applied. - ``total_size`` will not be calculated in the response unless - it has been included in a response field mask. The response + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response field mask can be provided to the method by using the URL parameter ``$fields`` or ``fields``, or by using the HTTP/gRPC header ``X-Goog-FieldMask``. diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/site_enums.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/site_enums.py new file mode 100644 index 000000000000..46e54da4e27c --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/site_enums.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "SiteDisapprovalReasonEnum", + "SiteApprovalStatusEnum", + }, +) + + +class SiteDisapprovalReasonEnum(proto.Message): + r"""Wrapper message for + [SiteDisapprovalReason][google.ads.admanager.v1.SiteDisapprovalReasonEnum.SiteDisapprovalReason] + + """ + + class SiteDisapprovalReason(proto.Enum): + r"""The list of possible policy violation types for a Site. + + Values: + SITE_DISAPPROVAL_REASON_UNSPECIFIED (0): + Default value. This value is unused. + CONTENT (1): + The site has content that violates policy. + OTHER (2): + Generic error type. + OWNERSHIP (3): + The parent must be an authorized seller of + the child network's inventory. + """ + SITE_DISAPPROVAL_REASON_UNSPECIFIED = 0 + CONTENT = 1 + OTHER = 2 + OWNERSHIP = 3 + + +class SiteApprovalStatusEnum(proto.Message): + r"""Wrapper message for + [SiteApprovalStatus][google.ads.admanager.v1.SiteApprovalStatusEnum.SiteApprovalStatus] + + """ + + class SiteApprovalStatus(proto.Enum): + r"""Represents the approval status of a site. + + Values: + SITE_APPROVAL_STATUS_UNSPECIFIED (0): + Default value. This value is unused. + APPROVED (1): + The site has been approved to serve ads. + DISAPPROVED (2): + The site has been disapproved from serving + ads. + DRAFT (3): + The default status with which a site is + created. + REQUIRES_REVIEW (4): + The site has been deactivated and is not + serving ads due to dormancy. It must be + resubmitted for approval. + UNCHECKED (5): + Once the site is submitted for approval, its + status changes from draft to unchecked. It will + be reviwed with an estimated turn-around time of + 24h. Such a site cannot serve ads. + """ + SITE_APPROVAL_STATUS_UNSPECIFIED = 0 + APPROVED = 1 + DISAPPROVED = 2 + DRAFT = 3 + REQUIRES_REVIEW = 4 + UNCHECKED = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/site_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/site_messages.py new file mode 100644 index 000000000000..a7ceb9fe8624 --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/site_messages.py @@ -0,0 +1,137 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +from google.protobuf import timestamp_pb2 # type: ignore +import proto # type: ignore + +from google.ads.admanager_v1.types import site_enums + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "Site", + "DisapprovalReason", + }, +) + + +class Site(proto.Message): + r"""A Site represents a domain owned or represented by a network. + For a parent network managing other networks as part of Multiple + Customer Management "Manage Inventory" model, it could be the + child's domain. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + Identifier. The resource name of the ``Site``. Format: + ``networks/{network_code}/sites/{site_id}`` + url (str): + Required. The URL of the Site. + + This field is a member of `oneof`_ ``_url``. + child_network_code (str): + Optional. The network code of the child if + the Site is being managed for an MCM child + network, or null if owned by this network. + + This field is a member of `oneof`_ ``_child_network_code``. + approval_status (google.ads.admanager_v1.types.SiteApprovalStatusEnum.SiteApprovalStatus): + Output only. Status of the review performed + on the Site by Google. + + This field is a member of `oneof`_ ``_approval_status``. + approval_status_update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The latest Site approval status + change time. + + This field is a member of `oneof`_ ``_approval_status_update_time``. + disapproval_reasons (MutableSequence[google.ads.admanager_v1.types.DisapprovalReason]): + Output only. Provides reasons for + disapproving the Site. It is null when the Site + is not disapproved. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + url: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + child_network_code: str = proto.Field( + proto.STRING, + number=4, + optional=True, + ) + approval_status: site_enums.SiteApprovalStatusEnum.SiteApprovalStatus = proto.Field( + proto.ENUM, + number=5, + optional=True, + enum=site_enums.SiteApprovalStatusEnum.SiteApprovalStatus, + ) + approval_status_update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + optional=True, + message=timestamp_pb2.Timestamp, + ) + disapproval_reasons: MutableSequence["DisapprovalReason"] = proto.RepeatedField( + proto.MESSAGE, + number=7, + message="DisapprovalReason", + ) + + +class DisapprovalReason(proto.Message): + r"""Represents the reason for which Google disapproved the Site. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + type_ (google.ads.admanager_v1.types.SiteDisapprovalReasonEnum.SiteDisapprovalReason): + Output only. The type of policy violation + found for the Site. + + This field is a member of `oneof`_ ``_type``. + details (str): + Output only. Additional details for the + disapproval of the Site. + + This field is a member of `oneof`_ ``_details``. + """ + + type_: site_enums.SiteDisapprovalReasonEnum.SiteDisapprovalReason = proto.Field( + proto.ENUM, + number=1, + optional=True, + enum=site_enums.SiteDisapprovalReasonEnum.SiteDisapprovalReason, + ) + details: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/site_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/site_service.py new file mode 100644 index 000000000000..c646b1f70a1e --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/site_service.py @@ -0,0 +1,339 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +from google.protobuf import field_mask_pb2 # type: ignore +import proto # type: ignore + +from google.ads.admanager_v1.types import site_messages + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "GetSiteRequest", + "ListSitesRequest", + "ListSitesResponse", + "CreateSiteRequest", + "BatchCreateSitesRequest", + "BatchCreateSitesResponse", + "UpdateSiteRequest", + "BatchUpdateSitesRequest", + "BatchUpdateSitesResponse", + "BatchDeactivateSitesRequest", + "BatchDeactivateSitesResponse", + "BatchSubmitSitesForApprovalRequest", + "BatchSubmitSitesForApprovalResponse", + }, +) + + +class GetSiteRequest(proto.Message): + r"""Request object for ``GetSite`` method. + + Attributes: + name (str): + Required. The resource name of the Site. Format: + ``networks/{network_code}/sites/{site_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListSitesRequest(proto.Message): + r"""Request object for ``ListSites`` method. + + Attributes: + parent (str): + Required. The parent, which owns this collection of Sites. + Format: ``networks/{network_code}`` + page_size (int): + Optional. The maximum number of ``Sites`` to return. The + service may return fewer than this value. If unspecified, at + most 50 ``Sites`` will be returned. The maximum value is + 1000; values greater than 1000 will be coerced to 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListSites`` call. Provide this to retrieve the subsequent + page. + + When paginating, all other parameters provided to + ``ListSites`` must match the call that provided the page + token. + filter (str): + Optional. Expression to filter the response. + See syntax details at + https://developers.google.com/ad-manager/api/beta/filters + order_by (str): + Optional. Expression to specify sorting + order. See syntax details at + https://developers.google.com/ad-manager/api/beta/filters#order + skip (int): + Optional. Number of individual resources to + skip while paginating. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + skip: int = proto.Field( + proto.INT32, + number=6, + ) + + +class ListSitesResponse(proto.Message): + r"""Response object for ``ListSitesRequest`` containing matching + ``Site`` objects. + + Attributes: + sites (MutableSequence[google.ads.admanager_v1.types.Site]): + The ``Site`` objects from the specified network. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + total_size (int): + Total number of ``Site`` objects. If a filter was included + in the request, this reflects the total number after the + filtering is applied. + + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response + field mask can be provided to the method by using the URL + parameter ``$fields`` or ``fields``, or by using the + HTTP/gRPC header ``X-Goog-FieldMask``. + + For more information, see + https://developers.google.com/ad-manager/api/beta/field-masks + """ + + @property + def raw_page(self): + return self + + sites: MutableSequence[site_messages.Site] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=site_messages.Site, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + + +class CreateSiteRequest(proto.Message): + r"""Request object for ``CreateSite`` method. + + Attributes: + parent (str): + Required. The parent resource where this ``Site`` will be + created. Format: ``networks/{network_code}`` + site (google.ads.admanager_v1.types.Site): + Required. The ``Site`` to create. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + site: site_messages.Site = proto.Field( + proto.MESSAGE, + number=2, + message=site_messages.Site, + ) + + +class BatchCreateSitesRequest(proto.Message): + r"""Request object for ``BatchCreateSites`` method. + + Attributes: + parent (str): + Required. The parent resource where ``Sites`` will be + created. Format: ``networks/{network_code}`` The parent + field in the CreateSiteRequest must match this field. + requests (MutableSequence[google.ads.admanager_v1.types.CreateSiteRequest]): + Required. The ``Site`` objects to create. A maximum of 100 + objects can be created in a batch. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + requests: MutableSequence["CreateSiteRequest"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="CreateSiteRequest", + ) + + +class BatchCreateSitesResponse(proto.Message): + r"""Response object for ``BatchCreateSites`` method. + + Attributes: + sites (MutableSequence[google.ads.admanager_v1.types.Site]): + The ``Site`` objects created. + """ + + sites: MutableSequence[site_messages.Site] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=site_messages.Site, + ) + + +class UpdateSiteRequest(proto.Message): + r"""Request object for ``UpdateSite`` method. + + Attributes: + site (google.ads.admanager_v1.types.Site): + Required. The ``Site`` to update. + + The ``Site``'s ``name`` is used to identify the ``Site`` to + update. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Required. The list of fields to update. + """ + + site: site_messages.Site = proto.Field( + proto.MESSAGE, + number=1, + message=site_messages.Site, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class BatchUpdateSitesRequest(proto.Message): + r"""Request object for ``BatchUpdateSites`` method. + + Attributes: + parent (str): + Required. The parent resource where ``Sites`` will be + updated. Format: ``networks/{network_code}`` The parent + field in the UpdateSiteRequest must match this field. + requests (MutableSequence[google.ads.admanager_v1.types.UpdateSiteRequest]): + Required. The ``Site`` objects to update. A maximum of 100 + objects can be updated in a batch. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + requests: MutableSequence["UpdateSiteRequest"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="UpdateSiteRequest", + ) + + +class BatchUpdateSitesResponse(proto.Message): + r"""Response object for ``BatchUpdateSites`` method. + + Attributes: + sites (MutableSequence[google.ads.admanager_v1.types.Site]): + The ``Site`` objects updated. + """ + + sites: MutableSequence[site_messages.Site] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=site_messages.Site, + ) + + +class BatchDeactivateSitesRequest(proto.Message): + r"""Request message for ``BatchDeactivateSites`` method. + + Attributes: + parent (str): + Required. Format: ``networks/{network_code}`` + names (MutableSequence[str]): + Required. The resource names of the ``Site`` objects to + deactivate. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class BatchDeactivateSitesResponse(proto.Message): + r"""Response object for ``BatchDeactivateSites`` method.""" + + +class BatchSubmitSitesForApprovalRequest(proto.Message): + r"""Request message for ``BatchSubmitSitesForApproval`` method. + + Attributes: + parent (str): + Required. Format: ``networks/{network_code}`` + names (MutableSequence[str]): + Required. The resource names of the ``Site`` objects to + submit for approval. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class BatchSubmitSitesForApprovalResponse(proto.Message): + r"""Response object for ``BatchSubmitSitesForApproval`` method.""" + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/targeting.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/targeting.py index bd59294cee89..1fa0ecd646a5 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/targeting.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/targeting.py @@ -32,7 +32,12 @@ "GeoTargeting", "TechnologyTargeting", "BandwidthTargeting", + "BrowserTargeting", + "BrowserLanguageTargeting", "DeviceCategoryTargeting", + "DeviceCapabilityTargeting", + "DeviceManufacturerTargeting", + "MobileCarrierTargeting", "OperatingSystemTargeting", "InventoryTargeting", "AdUnitTargeting", @@ -40,10 +45,15 @@ "CustomTargeting", "CustomTargetingClause", "CustomTargetingLiteral", + "AudienceSegmentTargeting", + "CmsMetadataTargeting", "UserDomainTargeting", "VideoPositionTargeting", "VideoPosition", "DataSegmentTargeting", + "ContentTargeting", + "MobileApplicationTargeting", + "FirstPartyMobileApplicationTargeting", }, ) @@ -73,6 +83,10 @@ class Targeting(proto.Message): Optional. Used to target video positions. data_segment_targeting (google.ads.admanager_v1.types.DataSegmentTargeting): Optional. Used to target data segments. + content_targeting (google.ads.admanager_v1.types.ContentTargeting): + Optional. Used to target content. + mobile_application_targeting (google.ads.admanager_v1.types.MobileApplicationTargeting): + Optional. Used to target mobile applications. """ geo_targeting: "GeoTargeting" = proto.Field( @@ -115,6 +129,16 @@ class Targeting(proto.Message): number=13, message="DataSegmentTargeting", ) + content_targeting: "ContentTargeting" = proto.Field( + proto.MESSAGE, + number=15, + message="ContentTargeting", + ) + mobile_application_targeting: "MobileApplicationTargeting" = proto.Field( + proto.MESSAGE, + number=18, + message="MobileApplicationTargeting", + ) class GeoTargeting(proto.Message): @@ -146,9 +170,22 @@ class TechnologyTargeting(proto.Message): Attributes: bandwidth_targeting (google.ads.admanager_v1.types.BandwidthTargeting): Optional. Bandwidth targeting dimension. + browser_targeting (google.ads.admanager_v1.types.BrowserTargeting): + Optional. Browser targeting dimension. + browser_language_targeting (google.ads.admanager_v1.types.BrowserLanguageTargeting): + Optional. Browser language targeting + dimension. + device_capability_targeting (google.ads.admanager_v1.types.DeviceCapabilityTargeting): + Optional. Device capability targeting + dimension. device_category_targeting (google.ads.admanager_v1.types.DeviceCategoryTargeting): Optional. Device category targeting dimension. + device_manufacturer_targeting (google.ads.admanager_v1.types.DeviceManufacturerTargeting): + Optional. Device manufacturer targeting + dimension. + mobile_carrier_targeting (google.ads.admanager_v1.types.MobileCarrierTargeting): + Optional. Mobile carrier targeting dimension. operating_system_targeting (google.ads.admanager_v1.types.OperatingSystemTargeting): Optional. Operating system targeting dimension. @@ -159,11 +196,36 @@ class TechnologyTargeting(proto.Message): number=3, message="BandwidthTargeting", ) + browser_targeting: "BrowserTargeting" = proto.Field( + proto.MESSAGE, + number=4, + message="BrowserTargeting", + ) + browser_language_targeting: "BrowserLanguageTargeting" = proto.Field( + proto.MESSAGE, + number=5, + message="BrowserLanguageTargeting", + ) + device_capability_targeting: "DeviceCapabilityTargeting" = proto.Field( + proto.MESSAGE, + number=6, + message="DeviceCapabilityTargeting", + ) device_category_targeting: "DeviceCategoryTargeting" = proto.Field( proto.MESSAGE, number=1, message="DeviceCategoryTargeting", ) + device_manufacturer_targeting: "DeviceManufacturerTargeting" = proto.Field( + proto.MESSAGE, + number=7, + message="DeviceManufacturerTargeting", + ) + mobile_carrier_targeting: "MobileCarrierTargeting" = proto.Field( + proto.MESSAGE, + number=8, + message="MobileCarrierTargeting", + ) operating_system_targeting: "OperatingSystemTargeting" = proto.Field( proto.MESSAGE, number=2, @@ -199,6 +261,60 @@ class BandwidthTargeting(proto.Message): ) +class BrowserTargeting(proto.Message): + r"""Browser Targeting. + + Allows publishers to target/exclude a browser type (e.g. Chrome, + Firefox, Safari). For more information, see + https://support.google.com/admanager/answer/2884033 (Targeting + types > Browser). + + Attributes: + targeted_browsers (MutableSequence[str]): + Optional. A list of browser resource names + that should be targeted/included. + excluded_browsers (MutableSequence[str]): + Optional. A list of browser resource names + that should be excluded. + """ + + targeted_browsers: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + excluded_browsers: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + + +class BrowserLanguageTargeting(proto.Message): + r"""Browser Language Targeting. + + For ads targeting mobile apps and their associated WebViews, the + language used is based on the language specified by the user in + their mobile device settings. If a browser has more than one + language assigned to it, each language generates an impression. + + Attributes: + targeted_browser_languages (MutableSequence[str]): + Optional. A list of browser language resource + names that should be targeted/included. + excluded_browser_languages (MutableSequence[str]): + Optional. A list of browser language resource + names that should be excluded. + """ + + targeted_browser_languages: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + excluded_browser_languages: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + + class DeviceCategoryTargeting(proto.Message): r"""Represents a list of targeted and excluded device categories. @@ -221,6 +337,114 @@ class DeviceCategoryTargeting(proto.Message): ) +class DeviceCapabilityTargeting(proto.Message): + r"""Device Capability Targeting. + + Can be used to target/exclude users using mobile apps, ad + requests resulting from apps built on the MRAID standard, or + users on devices that are able to make phone calls versus + devices that aren't able to make phone calls, such as tablets. + + Attributes: + targeted_capabilities (MutableSequence[str]): + Optional. A list of device capability + resource names that should be targeted/included. + excluded_capabilities (MutableSequence[str]): + Optional. A list of device capability + resource names that should be excluded. + """ + + targeted_capabilities: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + excluded_capabilities: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + + +class DeviceManufacturerTargeting(proto.Message): + r"""Device Manufacturer Targeting. + + Can be used to target/exclude users on devices made by specific + brands or companies, such as Apple, Google, Samsung and others. + For more information, see + https://support.google.com/admanager/answer/2884033 ("Targeting + types > Device manufacturer"). + + Attributes: + targeted_device_manufacturers (MutableSequence[str]): + Optional. A list of device manufacturer + resource names that should be targeted/included. + excluded_device_manufacturers (MutableSequence[str]): + Optional. A list of device manufacturer + resource names that should be excluded. + targeted_mobile_devices (MutableSequence[str]): + Optional. A list of mobile device resource + names that should be targeted/included. + excluded_mobile_devices (MutableSequence[str]): + Optional. A list of mobile device resource + names that should be excluded. + targeted_mobile_device_submodels (MutableSequence[str]): + Optional. A list of mobile device submodel + resource names that should be targeted/included. + excluded_mobile_device_submodels (MutableSequence[str]): + Optional. A list of mobile device submodel + resource names that should be excluded. + """ + + targeted_device_manufacturers: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=7, + ) + excluded_device_manufacturers: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=8, + ) + targeted_mobile_devices: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=9, + ) + excluded_mobile_devices: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=10, + ) + targeted_mobile_device_submodels: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=11, + ) + excluded_mobile_device_submodels: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=12, + ) + + +class MobileCarrierTargeting(proto.Message): + r"""Mobile Carrier Targeting. + + Can be used to target/exclude a variety of mobile carriers, such + as AT&T, Verizon, or T-Mobile. + + Attributes: + targeted_mobile_carriers (MutableSequence[str]): + Optional. A list of mobile carrier resource + names that should be targeted/included. + excluded_mobile_carriers (MutableSequence[str]): + Optional. A list of mobile carrier resource + names that should be excluded. + """ + + targeted_mobile_carriers: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + excluded_mobile_carriers: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + + class OperatingSystemTargeting(proto.Message): r"""Operating System Targeting @@ -370,6 +594,12 @@ class CustomTargetingClause(proto.Message): custom_targeting_literals (MutableSequence[google.ads.admanager_v1.types.CustomTargetingLiteral]): Optional. Leaf targeting expressions for custom key/values. + audience_segment_targetings (MutableSequence[google.ads.admanager_v1.types.AudienceSegmentTargeting]): + Optional. Leaf targeting expressions for + audience segments. + cms_metadata_targetings (MutableSequence[google.ads.admanager_v1.types.CmsMetadataTargeting]): + Optional. Leaf targeting expressions for cms + metadata. """ custom_targeting_literals: MutableSequence[ @@ -379,6 +609,20 @@ class CustomTargetingClause(proto.Message): number=1, message="CustomTargetingLiteral", ) + audience_segment_targetings: MutableSequence[ + "AudienceSegmentTargeting" + ] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="AudienceSegmentTargeting", + ) + cms_metadata_targetings: MutableSequence[ + "CmsMetadataTargeting" + ] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message="CmsMetadataTargeting", + ) class CustomTargetingLiteral(proto.Message): @@ -421,6 +665,73 @@ class CustomTargetingLiteral(proto.Message): ) +class AudienceSegmentTargeting(proto.Message): + r"""Represents targeting for audience segments. The values are combined + in a logical ``OR``. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + negative (bool): + Whether this expression is negatively + targeted, meaning it matches ad requests that + exclude the below values. + + This field is a member of `oneof`_ ``_negative``. + audience_segments (MutableSequence[str]): + Optional. The targeted audience segments. + + This is either the resource name of a first-party audience + segment or an alias to the effective third-party audience + segment. Third-party audience segment resource names + containing ``~direct`` or ``~global`` will be normalized by + the server. For example, + ``networks/1234/audienceSegments/4567~direct`` will be + normalized to ``networks/1234/audienceSegments/4567``. + """ + + negative: bool = proto.Field( + proto.BOOL, + number=1, + optional=True, + ) + audience_segments: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + +class CmsMetadataTargeting(proto.Message): + r"""Represents targeting for CMS metadata. The values are ORed + together. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + negative (bool): + Whether this expression is negatively + targeted, meaning it matches ad requests that + exclude the below values. + + This field is a member of `oneof`_ ``_negative``. + cms_metadata_values (MutableSequence[str]): + Optional. The resource names of the targeted + CMS metadata values. + """ + + negative: bool = proto.Field( + proto.BOOL, + number=1, + optional=True, + ) + cms_metadata_values: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + class UserDomainTargeting(proto.Message): r"""User Domain Targeting @@ -546,4 +857,91 @@ class DataSegmentTargeting(proto.Message): ) +class ContentTargeting(proto.Message): + r"""Content Targeting + + Targeted/excluded content entities and bundles. + + Attributes: + targeted_content (MutableSequence[str]): + Optional. The resource names of the + [Content][google.ads.admanager.v1.Content] that should be + targeted/included. + excluded_content (MutableSequence[str]): + Optional. The resource names of the + [Content][google.ads.admanager.v1.Content] that should be + excluded. + targeted_content_bundles (MutableSequence[str]): + Optional. The resource names of the + [ContentBundles][google.ads.admanager.v1.ContentBundle] that + should be targeted/included. + excluded_content_bundles (MutableSequence[str]): + Optional. The resource names of the + [ContentBundles][google.ads.admanager.v1.ContentBundle] that + should be excluded. + """ + + targeted_content: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + excluded_content: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=6, + ) + targeted_content_bundles: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=7, + ) + excluded_content_bundles: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=8, + ) + + +class MobileApplicationTargeting(proto.Message): + r"""Mobile Application Targeting + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + first_party_targeting (google.ads.admanager_v1.types.FirstPartyMobileApplicationTargeting): + Optional. The targeted/excluded first-party + mobile applications. + + This field is a member of `oneof`_ ``targeting``. + """ + + first_party_targeting: "FirstPartyMobileApplicationTargeting" = proto.Field( + proto.MESSAGE, + number=1, + oneof="targeting", + message="FirstPartyMobileApplicationTargeting", + ) + + +class FirstPartyMobileApplicationTargeting(proto.Message): + r"""First-party mobile application targeting. + + Attributes: + targeted_applications (MutableSequence[str]): + Optional. The resource names of the + first-party applications that should be + targeted. + excluded_applications (MutableSequence[str]): + Optional. The resource names of the + first-party applications that should be + excluded. + """ + + targeted_applications: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + excluded_applications: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/taxonomy_category_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/taxonomy_category_service.py index ceb3f13a7874..63cf0fb10999 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/taxonomy_category_service.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/taxonomy_category_service.py @@ -122,8 +122,8 @@ class ListTaxonomyCategoriesResponse(proto.Message): was included in the request, this reflects the total number after the filtering is applied. - ``total_size`` will not be calculated in the response unless - it has been included in a response field mask. The response + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response field mask can be provided to the method by using the URL parameter ``$fields`` or ``fields``, or by using the HTTP/gRPC header ``X-Goog-FieldMask``. diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/taxonomy_type_enum.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/taxonomy_type_enum.py index bc7aa8119fc3..e03d32877e47 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/taxonomy_type_enum.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/taxonomy_type_enum.py @@ -42,6 +42,8 @@ class TaxonomyType(proto.Enum): Unspecified/not present TAXONOMY_IAB_AUDIENCE_1_1 (3): The IAB Audience Taxonomy v1.1. + TAXONOMY_IAB_CONTENT_1_0 (8): + The IAB Content Taxonomy v1.0. TAXONOMY_IAB_CONTENT_2_1 (4): The IAB Content Taxonomy v2.1. TAXONOMY_IAB_CONTENT_2_2 (6): @@ -53,6 +55,7 @@ class TaxonomyType(proto.Enum): """ TAXONOMY_TYPE_UNSPECIFIED = 0 TAXONOMY_IAB_AUDIENCE_1_1 = 3 + TAXONOMY_IAB_CONTENT_1_0 = 8 TAXONOMY_IAB_CONTENT_2_1 = 4 TAXONOMY_IAB_CONTENT_2_2 = 6 TAXONOMY_IAB_CONTENT_3_0 = 5 diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/team_enums.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/team_enums.py new file mode 100644 index 000000000000..30932486144d --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/team_enums.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 + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "TeamStatusEnum", + "TeamAccessTypeEnum", + }, +) + + +class TeamStatusEnum(proto.Message): + r"""Wrapper message for + [TeamStatus][google.ads.admanager.v1.TeamStatusEnum.TeamStatus] + + """ + + class TeamStatus(proto.Enum): + r"""Represents the status of a team, whether it is active or + inactive. + + Values: + TEAM_STATUS_UNSPECIFIED (0): + Default value. This value is unused. + ACTIVE (1): + The status of an active team. + INACTIVE (2): + The status of an inactive team. + """ + TEAM_STATUS_UNSPECIFIED = 0 + ACTIVE = 1 + INACTIVE = 2 + + +class TeamAccessTypeEnum(proto.Message): + r"""Wrapper message for + [TeamAccessType][google.ads.admanager.v1.TeamAccessTypeEnum.TeamAccessType] + + """ + + class TeamAccessType(proto.Enum): + r"""Represents the types of team access supported for orders. + + Values: + TEAM_ACCESS_TYPE_UNSPECIFIED (0): + Default value. This value is unused. + NONE (1): + The level of access in which team members + can't view or edit a team's orders. + READ_ONLY (2): + The level of access in which team members can + only view a team's orders. + READ_WRITE (3): + The level of access in which team members can + view and edit a team's orders. + """ + TEAM_ACCESS_TYPE_UNSPECIFIED = 0 + NONE = 1 + READ_ONLY = 2 + READ_WRITE = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/team_messages.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/team_messages.py index 5b5d1edb5c0e..419cdac074a9 100644 --- a/packages/google-ads-admanager/google/ads/admanager_v1/types/team_messages.py +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/team_messages.py @@ -19,6 +19,8 @@ import proto # type: ignore +from google.ads.admanager_v1.types import team_enums + __protobuf__ = proto.module( package="google.ads.admanager.v1", manifest={ @@ -31,16 +33,86 @@ class Team(proto.Message): r"""A Team defines a grouping of users and what entities they have access to. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: name (str): Identifier. The resource name of the ``Team``. Format: ``networks/{network_code}/teams/{team_id}`` + display_name (str): + Required. The name of the Team. This value + has a maximum length of 127 characters. + + This field is a member of `oneof`_ ``_display_name``. + description (str): + Optional. The description of the Team. This + value has a maximum length of 255 characters. + + This field is a member of `oneof`_ ``_description``. + status (google.ads.admanager_v1.types.TeamStatusEnum.TeamStatus): + Output only. The status of the Team. This + value determines the visibility of the team in + the UI. + + This field is a member of `oneof`_ ``_status``. + all_companies_access (bool): + Optional. Whether or not users on this team + have access to all companies. If this value is + true, then an error will be thrown if an attempt + is made to associate this team with a Company. + + This field is a member of `oneof`_ ``_all_companies_access``. + all_inventory_access (bool): + Optional. Whether or not users on this team + have access to all inventory. If this value is + true, then an error will be thrown if an attempt + is made to associate this team with an AdUnit. + + This field is a member of `oneof`_ ``_all_inventory_access``. + access_type (google.ads.admanager_v1.types.TeamAccessTypeEnum.TeamAccessType): + Optional. The default access to orders for + users on this team. + + This field is a member of `oneof`_ ``_access_type``. """ name: str = proto.Field( proto.STRING, number=1, ) + display_name: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + description: str = proto.Field( + proto.STRING, + number=4, + optional=True, + ) + status: team_enums.TeamStatusEnum.TeamStatus = proto.Field( + proto.ENUM, + number=5, + optional=True, + enum=team_enums.TeamStatusEnum.TeamStatus, + ) + all_companies_access: bool = proto.Field( + proto.BOOL, + number=6, + optional=True, + ) + all_inventory_access: bool = proto.Field( + proto.BOOL, + number=7, + optional=True, + ) + access_type: team_enums.TeamAccessTypeEnum.TeamAccessType = proto.Field( + proto.ENUM, + number=8, + optional=True, + enum=team_enums.TeamAccessTypeEnum.TeamAccessType, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/team_service.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/team_service.py new file mode 100644 index 000000000000..ad7ca1e8e61e --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/team_service.py @@ -0,0 +1,340 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +from google.protobuf import field_mask_pb2 # type: ignore +import proto # type: ignore + +from google.ads.admanager_v1.types import team_messages + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "GetTeamRequest", + "ListTeamsRequest", + "ListTeamsResponse", + "CreateTeamRequest", + "BatchCreateTeamsRequest", + "BatchCreateTeamsResponse", + "UpdateTeamRequest", + "BatchUpdateTeamsRequest", + "BatchUpdateTeamsResponse", + "BatchActivateTeamsRequest", + "BatchActivateTeamsResponse", + "BatchDeactivateTeamsRequest", + "BatchDeactivateTeamsResponse", + }, +) + + +class GetTeamRequest(proto.Message): + r"""Request object for ``GetTeam`` method. + + Attributes: + name (str): + Required. The resource name of the Team. Format: + ``networks/{network_code}/teams/{team_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListTeamsRequest(proto.Message): + r"""Request object for ``ListTeams`` method. + + Attributes: + parent (str): + Required. The parent, which owns this collection of Teams. + Format: ``networks/{network_code}`` + page_size (int): + Optional. The maximum number of ``Teams`` to return. The + service may return fewer than this value. If unspecified, at + most 50 ``Teams`` will be returned. The maximum value is + 1000; values greater than 1000 will be coerced to 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListTeams`` call. Provide this to retrieve the subsequent + page. + + When paginating, all other parameters provided to + ``ListTeams`` must match the call that provided the page + token. + filter (str): + Optional. Expression to filter the response. + See syntax details at + https://developers.google.com/ad-manager/api/beta/filters + order_by (str): + Optional. Expression to specify sorting + order. See syntax details at + https://developers.google.com/ad-manager/api/beta/filters#order + skip (int): + Optional. Number of individual resources to + skip while paginating. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + order_by: str = proto.Field( + proto.STRING, + number=5, + ) + skip: int = proto.Field( + proto.INT32, + number=6, + ) + + +class ListTeamsResponse(proto.Message): + r"""Response object for ``ListTeamsRequest`` containing matching + ``Team`` objects. + + Attributes: + teams (MutableSequence[google.ads.admanager_v1.types.Team]): + The ``Team`` objects from the specified network. + next_page_token (str): + A token, which can be sent as ``page_token`` to retrieve the + next page. If this field is omitted, there are no subsequent + pages. + total_size (int): + Total number of ``Team`` objects. If a filter was included + in the request, this reflects the total number after the + filtering is applied. + + ``total_size`` won't be calculated in the response unless it + has been included in a response field mask. The response + field mask can be provided to the method by using the URL + parameter ``$fields`` or ``fields``, or by using the + HTTP/gRPC header ``X-Goog-FieldMask``. + + For more information, see + https://developers.google.com/ad-manager/api/beta/field-masks + """ + + @property + def raw_page(self): + return self + + teams: MutableSequence[team_messages.Team] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=team_messages.Team, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + + +class CreateTeamRequest(proto.Message): + r"""Request object for ``CreateTeam`` method. + + Attributes: + parent (str): + Required. The parent resource where this ``Team`` will be + created. Format: ``networks/{network_code}`` + team (google.ads.admanager_v1.types.Team): + Required. The ``Team`` to create. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + team: team_messages.Team = proto.Field( + proto.MESSAGE, + number=2, + message=team_messages.Team, + ) + + +class BatchCreateTeamsRequest(proto.Message): + r"""Request object for ``BatchCreateTeams`` method. + + Attributes: + parent (str): + Required. The parent resource where ``Teams`` will be + created. Format: ``networks/{network_code}`` The parent + field in the CreateTeamRequest must match this field. + requests (MutableSequence[google.ads.admanager_v1.types.CreateTeamRequest]): + Required. The ``Team`` objects to create. A maximum of 100 + objects can be created in a batch. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + requests: MutableSequence["CreateTeamRequest"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="CreateTeamRequest", + ) + + +class BatchCreateTeamsResponse(proto.Message): + r"""Response object for ``BatchCreateTeams`` method. + + Attributes: + teams (MutableSequence[google.ads.admanager_v1.types.Team]): + The ``Team`` objects created. + """ + + teams: MutableSequence[team_messages.Team] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=team_messages.Team, + ) + + +class UpdateTeamRequest(proto.Message): + r"""Request object for ``UpdateTeam`` method. + + Attributes: + team (google.ads.admanager_v1.types.Team): + Required. The ``Team`` to update. + + The ``Team``'s ``name`` is used to identify the ``Team`` to + update. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Required. The list of fields to update. + """ + + team: team_messages.Team = proto.Field( + proto.MESSAGE, + number=1, + message=team_messages.Team, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class BatchUpdateTeamsRequest(proto.Message): + r"""Request object for ``BatchUpdateTeams`` method. + + Attributes: + parent (str): + Required. The parent resource where ``Teams`` will be + updated. Format: ``networks/{network_code}`` The parent + field in the UpdateTeamRequest must match this field. + requests (MutableSequence[google.ads.admanager_v1.types.UpdateTeamRequest]): + Required. The ``Team`` objects to update. A maximum of 100 + objects can be updated in a batch. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + requests: MutableSequence["UpdateTeamRequest"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="UpdateTeamRequest", + ) + + +class BatchUpdateTeamsResponse(proto.Message): + r"""Response object for ``BatchUpdateTeams`` method. + + Attributes: + teams (MutableSequence[google.ads.admanager_v1.types.Team]): + The ``Team`` objects updated. + """ + + teams: MutableSequence[team_messages.Team] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=team_messages.Team, + ) + + +class BatchActivateTeamsRequest(proto.Message): + r"""Request message for ``BatchActivateTeams`` method. + + Attributes: + parent (str): + Required. Format: ``networks/{network_code}`` + names (MutableSequence[str]): + Required. The resource names of the ``Team``\ s to activate. + Format: ``networks/{network_code}/teams/{team_id}`` + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class BatchActivateTeamsResponse(proto.Message): + r"""Response object for ``BatchActivateTeams`` method.""" + + +class BatchDeactivateTeamsRequest(proto.Message): + r"""Request message for ``BatchDeactivateTeams`` method. + + Attributes: + parent (str): + Required. Format: ``networks/{network_code}`` + names (MutableSequence[str]): + Required. The resource names of the ``Team``\ s to + deactivate. Format: + ``networks/{network_code}/teams/{team_id}`` + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class BatchDeactivateTeamsResponse(proto.Message): + r"""Response object for ``BatchDeactivateTeams`` method.""" + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/google/ads/admanager_v1/types/web_property.py b/packages/google-ads-admanager/google/ads/admanager_v1/types/web_property.py new file mode 100644 index 000000000000..ba1ebe28cdcf --- /dev/null +++ b/packages/google-ads-admanager/google/ads/admanager_v1/types/web_property.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 + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.ads.admanager_v1.types import exchange_syndication_product_enum + +__protobuf__ = proto.module( + package="google.ads.admanager.v1", + manifest={ + "WebProperty", + }, +) + + +class WebProperty(proto.Message): + r"""Represents a web property. + + Attributes: + name (str): + Identifier. The resource name of the WebProperty. Format: + ``networks/{network_code}/webProperties/{web_property_code}`` + web_property_code (str): + Required. The ``WebProperty`` code. + product_type (google.ads.admanager_v1.types.ExchangeSyndicationProductEnum.ExchangeSyndicationProduct): + Required. The ExchangeSyndicationProduct + associated with this WebProperty. + web_property_id (int): + Optional. The ``WebProperty`` ID. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + web_property_code: str = proto.Field( + proto.STRING, + number=2, + ) + product_type: exchange_syndication_product_enum.ExchangeSyndicationProductEnum.ExchangeSyndicationProduct = proto.Field( + proto.ENUM, + number=3, + enum=exchange_syndication_product_enum.ExchangeSyndicationProductEnum.ExchangeSyndicationProduct, + ) + web_property_id: int = proto.Field( + proto.INT64, + number=4, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-ads-admanager/noxfile.py b/packages/google-ads-admanager/noxfile.py index ce9d4dd2657a..f5011758666f 100644 --- a/packages/google-ads-admanager/noxfile.py +++ b/packages/google-ads-admanager/noxfile.py @@ -27,6 +27,10 @@ LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] +# Add samples to the list of directories to format if the directory exists. +if os.path.isdir("samples"): + LINT_PATHS.append("samples") + ALL_PYTHON = [ "3.7", "3.8", diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_break_service_create_ad_break_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_break_service_create_ad_break_sync.py index 182e7491039e..3d5d6d661855 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_break_service_create_ad_break_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_break_service_create_ad_break_sync.py @@ -49,4 +49,5 @@ def sample_create_ad_break(): # Handle the response print(response) + # [END admanager_v1_generated_AdBreakService_CreateAdBreak_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_break_service_get_ad_break_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_break_service_get_ad_break_sync.py index caa24caefd63..ca098721213e 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_break_service_get_ad_break_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_break_service_get_ad_break_sync.py @@ -49,4 +49,5 @@ def sample_get_ad_break(): # Handle the response print(response) + # [END admanager_v1_generated_AdBreakService_GetAdBreak_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_break_service_list_ad_breaks_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_break_service_list_ad_breaks_sync.py index de8b9b98be2a..b4619591b1cf 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_break_service_list_ad_breaks_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_break_service_list_ad_breaks_sync.py @@ -50,4 +50,5 @@ def sample_list_ad_breaks(): for response in page_result: print(response) + # [END admanager_v1_generated_AdBreakService_ListAdBreaks_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_break_service_update_ad_break_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_break_service_update_ad_break_sync.py index 4967a8b6047e..7ace88537607 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_break_service_update_ad_break_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_break_service_update_ad_break_sync.py @@ -39,8 +39,7 @@ def sample_update_ad_break(): client = admanager_v1.AdBreakServiceClient() # Initialize request argument(s) - request = admanager_v1.UpdateAdBreakRequest( - ) + request = admanager_v1.UpdateAdBreakRequest() # Make the request response = client.update_ad_break(request=request) @@ -48,4 +47,5 @@ def sample_update_ad_break(): # Handle the response print(response) + # [END admanager_v1_generated_AdBreakService_UpdateAdBreak_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_review_center_ad_service_batch_allow_ad_review_center_ads_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_review_center_ad_service_batch_allow_ad_review_center_ads_sync.py new file mode 100644 index 000000000000..9087129cacf0 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_review_center_ad_service_batch_allow_ad_review_center_ads_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchAllowAdReviewCenterAds +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_AdReviewCenterAdService_BatchAllowAdReviewCenterAds_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_batch_allow_ad_review_center_ads(): + # Create a client + client = admanager_v1.AdReviewCenterAdServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchAllowAdReviewCenterAdsRequest( + parent="parent_value", + names=["names_value1", "names_value2"], + ) + + # Make the request + operation = client.batch_allow_ad_review_center_ads(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END admanager_v1_generated_AdReviewCenterAdService_BatchAllowAdReviewCenterAds_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_review_center_ad_service_batch_block_ad_review_center_ads_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_review_center_ad_service_batch_block_ad_review_center_ads_sync.py new file mode 100644 index 000000000000..7a6be99cc2b6 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_review_center_ad_service_batch_block_ad_review_center_ads_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchBlockAdReviewCenterAds +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_AdReviewCenterAdService_BatchBlockAdReviewCenterAds_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_batch_block_ad_review_center_ads(): + # Create a client + client = admanager_v1.AdReviewCenterAdServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchBlockAdReviewCenterAdsRequest( + parent="parent_value", + names=["names_value1", "names_value2"], + ) + + # Make the request + operation = client.batch_block_ad_review_center_ads(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END admanager_v1_generated_AdReviewCenterAdService_BatchBlockAdReviewCenterAds_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_review_center_ad_service_search_ad_review_center_ads_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_review_center_ad_service_search_ad_review_center_ads_sync.py new file mode 100644 index 000000000000..4dc1ee75e6d8 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_review_center_ad_service_search_ad_review_center_ads_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for SearchAdReviewCenterAds +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_AdReviewCenterAdService_SearchAdReviewCenterAds_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_search_ad_review_center_ads(): + # Create a client + client = admanager_v1.AdReviewCenterAdServiceClient() + + # Initialize request argument(s) + request = admanager_v1.SearchAdReviewCenterAdsRequest( + parent="parent_value", + status="UNREVIEWED", + ) + + # Make the request + page_result = client.search_ad_review_center_ads(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END admanager_v1_generated_AdReviewCenterAdService_SearchAdReviewCenterAds_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_unit_service_get_ad_unit_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_unit_service_get_ad_unit_sync.py index c617b9efcf53..be216e0b22f6 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_unit_service_get_ad_unit_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_unit_service_get_ad_unit_sync.py @@ -49,4 +49,5 @@ def sample_get_ad_unit(): # Handle the response print(response) + # [END admanager_v1_generated_AdUnitService_GetAdUnit_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_unit_service_list_ad_unit_sizes_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_unit_service_list_ad_unit_sizes_sync.py index b4060600aac8..abb7178a8f9c 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_unit_service_list_ad_unit_sizes_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_unit_service_list_ad_unit_sizes_sync.py @@ -50,4 +50,5 @@ def sample_list_ad_unit_sizes(): for response in page_result: print(response) + # [END admanager_v1_generated_AdUnitService_ListAdUnitSizes_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_unit_service_list_ad_units_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_unit_service_list_ad_units_sync.py index 9b2493ab5856..6d644c645a67 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_unit_service_list_ad_units_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_ad_unit_service_list_ad_units_sync.py @@ -50,4 +50,5 @@ def sample_list_ad_units(): for response in page_result: print(response) + # [END admanager_v1_generated_AdUnitService_ListAdUnits_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_application_service_get_application_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_application_service_get_application_sync.py new file mode 100644 index 000000000000..7e156ef21964 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_application_service_get_application_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetApplication +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_ApplicationService_GetApplication_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_get_application(): + # Create a client + client = admanager_v1.ApplicationServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetApplicationRequest( + name="name_value", + ) + + # Make the request + response = client.get_application(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_ApplicationService_GetApplication_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_application_service_list_applications_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_application_service_list_applications_sync.py new file mode 100644 index 000000000000..ed290993a2c7 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_application_service_list_applications_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListApplications +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_ApplicationService_ListApplications_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_list_applications(): + # Create a client + client = admanager_v1.ApplicationServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListApplicationsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_applications(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END admanager_v1_generated_ApplicationService_ListApplications_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_audience_segment_service_get_audience_segment_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_audience_segment_service_get_audience_segment_sync.py new file mode 100644 index 000000000000..37d92fa9f75d --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_audience_segment_service_get_audience_segment_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetAudienceSegment +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_AudienceSegmentService_GetAudienceSegment_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_get_audience_segment(): + # Create a client + client = admanager_v1.AudienceSegmentServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetAudienceSegmentRequest( + name="name_value", + ) + + # Make the request + response = client.get_audience_segment(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_AudienceSegmentService_GetAudienceSegment_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_audience_segment_service_list_audience_segments_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_audience_segment_service_list_audience_segments_sync.py new file mode 100644 index 000000000000..35c70064378c --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_audience_segment_service_list_audience_segments_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListAudienceSegments +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_AudienceSegmentService_ListAudienceSegments_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_list_audience_segments(): + # Create a client + client = admanager_v1.AudienceSegmentServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListAudienceSegmentsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_audience_segments(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END admanager_v1_generated_AudienceSegmentService_ListAudienceSegments_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_bandwidth_group_service_get_bandwidth_group_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_bandwidth_group_service_get_bandwidth_group_sync.py index 0cf10969d616..7aaa6f4a2f53 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_bandwidth_group_service_get_bandwidth_group_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_bandwidth_group_service_get_bandwidth_group_sync.py @@ -49,4 +49,5 @@ def sample_get_bandwidth_group(): # Handle the response print(response) + # [END admanager_v1_generated_BandwidthGroupService_GetBandwidthGroup_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_bandwidth_group_service_list_bandwidth_groups_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_bandwidth_group_service_list_bandwidth_groups_sync.py index 0b88ef1213ad..b279f5dad001 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_bandwidth_group_service_list_bandwidth_groups_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_bandwidth_group_service_list_bandwidth_groups_sync.py @@ -50,4 +50,5 @@ def sample_list_bandwidth_groups(): for response in page_result: print(response) + # [END admanager_v1_generated_BandwidthGroupService_ListBandwidthGroups_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_browser_language_service_get_browser_language_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_browser_language_service_get_browser_language_sync.py new file mode 100644 index 000000000000..338f1291a1cd --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_browser_language_service_get_browser_language_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetBrowserLanguage +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_BrowserLanguageService_GetBrowserLanguage_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_get_browser_language(): + # Create a client + client = admanager_v1.BrowserLanguageServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetBrowserLanguageRequest( + name="name_value", + ) + + # Make the request + response = client.get_browser_language(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_BrowserLanguageService_GetBrowserLanguage_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_browser_language_service_list_browser_languages_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_browser_language_service_list_browser_languages_sync.py new file mode 100644 index 000000000000..47bfaaf5ecdc --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_browser_language_service_list_browser_languages_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListBrowserLanguages +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_BrowserLanguageService_ListBrowserLanguages_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_list_browser_languages(): + # Create a client + client = admanager_v1.BrowserLanguageServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListBrowserLanguagesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_browser_languages(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END admanager_v1_generated_BrowserLanguageService_ListBrowserLanguages_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_browser_service_get_browser_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_browser_service_get_browser_sync.py new file mode 100644 index 000000000000..8cce0db473b2 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_browser_service_get_browser_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetBrowser +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_BrowserService_GetBrowser_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_get_browser(): + # Create a client + client = admanager_v1.BrowserServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetBrowserRequest( + name="name_value", + ) + + # Make the request + response = client.get_browser(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_BrowserService_GetBrowser_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_browser_service_list_browsers_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_browser_service_list_browsers_sync.py new file mode 100644 index 000000000000..410ec7876570 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_browser_service_list_browsers_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListBrowsers +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_BrowserService_ListBrowsers_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_list_browsers(): + # Create a client + client = admanager_v1.BrowserServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListBrowsersRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_browsers(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END admanager_v1_generated_BrowserService_ListBrowsers_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_cms_metadata_key_service_get_cms_metadata_key_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_cms_metadata_key_service_get_cms_metadata_key_sync.py new file mode 100644 index 000000000000..eda0a2379676 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_cms_metadata_key_service_get_cms_metadata_key_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetCmsMetadataKey +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_CmsMetadataKeyService_GetCmsMetadataKey_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_get_cms_metadata_key(): + # Create a client + client = admanager_v1.CmsMetadataKeyServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetCmsMetadataKeyRequest( + name="name_value", + ) + + # Make the request + response = client.get_cms_metadata_key(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_CmsMetadataKeyService_GetCmsMetadataKey_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_cms_metadata_key_service_list_cms_metadata_keys_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_cms_metadata_key_service_list_cms_metadata_keys_sync.py new file mode 100644 index 000000000000..1748065ce8cd --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_cms_metadata_key_service_list_cms_metadata_keys_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListCmsMetadataKeys +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_CmsMetadataKeyService_ListCmsMetadataKeys_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_list_cms_metadata_keys(): + # Create a client + client = admanager_v1.CmsMetadataKeyServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListCmsMetadataKeysRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_cms_metadata_keys(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END admanager_v1_generated_CmsMetadataKeyService_ListCmsMetadataKeys_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_cms_metadata_value_service_get_cms_metadata_value_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_cms_metadata_value_service_get_cms_metadata_value_sync.py new file mode 100644 index 000000000000..696b751a4ea8 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_cms_metadata_value_service_get_cms_metadata_value_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetCmsMetadataValue +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_CmsMetadataValueService_GetCmsMetadataValue_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_get_cms_metadata_value(): + # Create a client + client = admanager_v1.CmsMetadataValueServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetCmsMetadataValueRequest( + name="name_value", + ) + + # Make the request + response = client.get_cms_metadata_value(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_CmsMetadataValueService_GetCmsMetadataValue_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_cms_metadata_value_service_list_cms_metadata_values_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_cms_metadata_value_service_list_cms_metadata_values_sync.py new file mode 100644 index 000000000000..75450ff33268 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_cms_metadata_value_service_list_cms_metadata_values_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListCmsMetadataValues +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_CmsMetadataValueService_ListCmsMetadataValues_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_list_cms_metadata_values(): + # Create a client + client = admanager_v1.CmsMetadataValueServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListCmsMetadataValuesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_cms_metadata_values(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END admanager_v1_generated_CmsMetadataValueService_ListCmsMetadataValues_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_company_service_get_company_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_company_service_get_company_sync.py index 6ab1a8ab3bd3..ceaaa91c6ad8 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_company_service_get_company_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_company_service_get_company_sync.py @@ -49,4 +49,5 @@ def sample_get_company(): # Handle the response print(response) + # [END admanager_v1_generated_CompanyService_GetCompany_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_company_service_list_companies_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_company_service_list_companies_sync.py index dc90aa3c706c..493d41eded40 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_company_service_list_companies_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_company_service_list_companies_sync.py @@ -50,4 +50,5 @@ def sample_list_companies(): for response in page_result: print(response) + # [END admanager_v1_generated_CompanyService_ListCompanies_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_contact_service_batch_create_contacts_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_contact_service_batch_create_contacts_sync.py new file mode 100644 index 000000000000..61f37a92c80b --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_contact_service_batch_create_contacts_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchCreateContacts +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_ContactService_BatchCreateContacts_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_batch_create_contacts(): + # Create a client + client = admanager_v1.ContactServiceClient() + + # Initialize request argument(s) + requests = admanager_v1.CreateContactRequest() + requests.parent = "parent_value" + + request = admanager_v1.BatchCreateContactsRequest( + parent="parent_value", + requests=requests, + ) + + # Make the request + response = client.batch_create_contacts(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_ContactService_BatchCreateContacts_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_contact_service_batch_update_contacts_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_contact_service_batch_update_contacts_sync.py new file mode 100644 index 000000000000..0bf907eca105 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_contact_service_batch_update_contacts_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchUpdateContacts +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_ContactService_BatchUpdateContacts_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_batch_update_contacts(): + # Create a client + client = admanager_v1.ContactServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchUpdateContactsRequest( + parent="parent_value", + ) + + # Make the request + response = client.batch_update_contacts(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_ContactService_BatchUpdateContacts_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_contact_service_create_contact_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_contact_service_create_contact_sync.py new file mode 100644 index 000000000000..aa40f6d01b96 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_contact_service_create_contact_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateContact +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_ContactService_CreateContact_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_create_contact(): + # Create a client + client = admanager_v1.ContactServiceClient() + + # Initialize request argument(s) + request = admanager_v1.CreateContactRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_contact(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_ContactService_CreateContact_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_contact_service_get_contact_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_contact_service_get_contact_sync.py new file mode 100644 index 000000000000..19ae2d66fa88 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_contact_service_get_contact_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetContact +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_ContactService_GetContact_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_get_contact(): + # Create a client + client = admanager_v1.ContactServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetContactRequest( + name="name_value", + ) + + # Make the request + response = client.get_contact(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_ContactService_GetContact_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_contact_service_list_contacts_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_contact_service_list_contacts_sync.py new file mode 100644 index 000000000000..e7383d388236 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_contact_service_list_contacts_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListContacts +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_ContactService_ListContacts_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_list_contacts(): + # Create a client + client = admanager_v1.ContactServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListContactsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_contacts(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END admanager_v1_generated_ContactService_ListContacts_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_contact_service_update_contact_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_contact_service_update_contact_sync.py new file mode 100644 index 000000000000..5ed5c4eae664 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_contact_service_update_contact_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateContact +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_ContactService_UpdateContact_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_update_contact(): + # Create a client + client = admanager_v1.ContactServiceClient() + + # Initialize request argument(s) + request = admanager_v1.UpdateContactRequest() + + # Make the request + response = client.update_contact(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_ContactService_UpdateContact_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_content_bundle_service_get_content_bundle_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_content_bundle_service_get_content_bundle_sync.py new file mode 100644 index 000000000000..23f95404f6a1 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_content_bundle_service_get_content_bundle_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetContentBundle +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_ContentBundleService_GetContentBundle_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_get_content_bundle(): + # Create a client + client = admanager_v1.ContentBundleServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetContentBundleRequest( + name="name_value", + ) + + # Make the request + response = client.get_content_bundle(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_ContentBundleService_GetContentBundle_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_content_bundle_service_list_content_bundles_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_content_bundle_service_list_content_bundles_sync.py new file mode 100644 index 000000000000..384a49ea45e4 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_content_bundle_service_list_content_bundles_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListContentBundles +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_ContentBundleService_ListContentBundles_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_list_content_bundles(): + # Create a client + client = admanager_v1.ContentBundleServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListContentBundlesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_content_bundles(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END admanager_v1_generated_ContentBundleService_ListContentBundles_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_content_label_service_get_content_label_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_content_label_service_get_content_label_sync.py new file mode 100644 index 000000000000..13573c835452 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_content_label_service_get_content_label_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetContentLabel +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_ContentLabelService_GetContentLabel_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_get_content_label(): + # Create a client + client = admanager_v1.ContentLabelServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetContentLabelRequest( + name="name_value", + ) + + # Make the request + response = client.get_content_label(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_ContentLabelService_GetContentLabel_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_content_label_service_list_content_labels_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_content_label_service_list_content_labels_sync.py new file mode 100644 index 000000000000..73b965d2e77b --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_content_label_service_list_content_labels_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListContentLabels +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_ContentLabelService_ListContentLabels_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_list_content_labels(): + # Create a client + client = admanager_v1.ContentLabelServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListContentLabelsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_content_labels(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END admanager_v1_generated_ContentLabelService_ListContentLabels_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_content_service_get_content_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_content_service_get_content_sync.py new file mode 100644 index 000000000000..91a72a1b31de --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_content_service_get_content_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetContent +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_ContentService_GetContent_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_get_content(): + # Create a client + client = admanager_v1.ContentServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetContentRequest( + name="name_value", + ) + + # Make the request + response = client.get_content(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_ContentService_GetContent_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_content_service_list_content_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_content_service_list_content_sync.py new file mode 100644 index 000000000000..93c77c4f01bf --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_content_service_list_content_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListContent +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_ContentService_ListContent_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_list_content(): + # Create a client + client = admanager_v1.ContentServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListContentRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_content(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END admanager_v1_generated_ContentService_ListContent_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_creative_template_service_get_creative_template_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_creative_template_service_get_creative_template_sync.py new file mode 100644 index 000000000000..9cdf1d319566 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_creative_template_service_get_creative_template_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetCreativeTemplate +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_CreativeTemplateService_GetCreativeTemplate_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_get_creative_template(): + # Create a client + client = admanager_v1.CreativeTemplateServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetCreativeTemplateRequest( + name="name_value", + ) + + # Make the request + response = client.get_creative_template(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_CreativeTemplateService_GetCreativeTemplate_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_creative_template_service_list_creative_templates_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_creative_template_service_list_creative_templates_sync.py new file mode 100644 index 000000000000..825ff3e07630 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_creative_template_service_list_creative_templates_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListCreativeTemplates +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_CreativeTemplateService_ListCreativeTemplates_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_list_creative_templates(): + # Create a client + client = admanager_v1.CreativeTemplateServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListCreativeTemplatesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_creative_templates(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END admanager_v1_generated_CreativeTemplateService_ListCreativeTemplates_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_batch_activate_custom_fields_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_batch_activate_custom_fields_sync.py new file mode 100644 index 000000000000..359a17ddbee6 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_batch_activate_custom_fields_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchActivateCustomFields +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_CustomFieldService_BatchActivateCustomFields_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_batch_activate_custom_fields(): + # Create a client + client = admanager_v1.CustomFieldServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchActivateCustomFieldsRequest( + parent="parent_value", + names=["names_value1", "names_value2"], + ) + + # Make the request + response = client.batch_activate_custom_fields(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_CustomFieldService_BatchActivateCustomFields_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_batch_create_custom_fields_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_batch_create_custom_fields_sync.py new file mode 100644 index 000000000000..9298f555bdbe --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_batch_create_custom_fields_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchCreateCustomFields +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_CustomFieldService_BatchCreateCustomFields_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_batch_create_custom_fields(): + # Create a client + client = admanager_v1.CustomFieldServiceClient() + + # Initialize request argument(s) + requests = admanager_v1.CreateCustomFieldRequest() + requests.parent = "parent_value" + + request = admanager_v1.BatchCreateCustomFieldsRequest( + parent="parent_value", + requests=requests, + ) + + # Make the request + response = client.batch_create_custom_fields(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_CustomFieldService_BatchCreateCustomFields_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_batch_deactivate_custom_fields_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_batch_deactivate_custom_fields_sync.py new file mode 100644 index 000000000000..2c5dfbcdb188 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_batch_deactivate_custom_fields_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchDeactivateCustomFields +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_CustomFieldService_BatchDeactivateCustomFields_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_batch_deactivate_custom_fields(): + # Create a client + client = admanager_v1.CustomFieldServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchDeactivateCustomFieldsRequest( + parent="parent_value", + names=["names_value1", "names_value2"], + ) + + # Make the request + response = client.batch_deactivate_custom_fields(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_CustomFieldService_BatchDeactivateCustomFields_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_batch_update_custom_fields_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_batch_update_custom_fields_sync.py new file mode 100644 index 000000000000..b4a7828acf22 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_batch_update_custom_fields_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchUpdateCustomFields +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_CustomFieldService_BatchUpdateCustomFields_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_batch_update_custom_fields(): + # Create a client + client = admanager_v1.CustomFieldServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchUpdateCustomFieldsRequest( + parent="parent_value", + ) + + # Make the request + response = client.batch_update_custom_fields(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_CustomFieldService_BatchUpdateCustomFields_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_create_custom_field_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_create_custom_field_sync.py new file mode 100644 index 000000000000..4666d27ccf2e --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_create_custom_field_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateCustomField +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_CustomFieldService_CreateCustomField_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_create_custom_field(): + # Create a client + client = admanager_v1.CustomFieldServiceClient() + + # Initialize request argument(s) + request = admanager_v1.CreateCustomFieldRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_custom_field(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_CustomFieldService_CreateCustomField_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_get_custom_field_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_get_custom_field_sync.py index ad0e2bac5898..ebca9492bb95 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_get_custom_field_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_get_custom_field_sync.py @@ -49,4 +49,5 @@ def sample_get_custom_field(): # Handle the response print(response) + # [END admanager_v1_generated_CustomFieldService_GetCustomField_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_list_custom_fields_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_list_custom_fields_sync.py index c3628197f4b8..ef52a3472fd6 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_list_custom_fields_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_list_custom_fields_sync.py @@ -50,4 +50,5 @@ def sample_list_custom_fields(): for response in page_result: print(response) + # [END admanager_v1_generated_CustomFieldService_ListCustomFields_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_update_custom_field_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_update_custom_field_sync.py new file mode 100644 index 000000000000..b073ea2e5b79 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_field_service_update_custom_field_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateCustomField +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_CustomFieldService_UpdateCustomField_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_update_custom_field(): + # Create a client + client = admanager_v1.CustomFieldServiceClient() + + # Initialize request argument(s) + request = admanager_v1.UpdateCustomFieldRequest() + + # Make the request + response = client.update_custom_field(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_CustomFieldService_UpdateCustomField_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_targeting_key_service_get_custom_targeting_key_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_targeting_key_service_get_custom_targeting_key_sync.py index 5b076b269235..3d631d0743ad 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_targeting_key_service_get_custom_targeting_key_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_targeting_key_service_get_custom_targeting_key_sync.py @@ -49,4 +49,5 @@ def sample_get_custom_targeting_key(): # Handle the response print(response) + # [END admanager_v1_generated_CustomTargetingKeyService_GetCustomTargetingKey_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_targeting_key_service_list_custom_targeting_keys_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_targeting_key_service_list_custom_targeting_keys_sync.py index 05a9a094810c..c25ca816bbf0 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_targeting_key_service_list_custom_targeting_keys_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_targeting_key_service_list_custom_targeting_keys_sync.py @@ -50,4 +50,5 @@ def sample_list_custom_targeting_keys(): for response in page_result: print(response) + # [END admanager_v1_generated_CustomTargetingKeyService_ListCustomTargetingKeys_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_targeting_value_service_get_custom_targeting_value_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_targeting_value_service_get_custom_targeting_value_sync.py index ae2f2d86d3ed..0e8dd6d5cd83 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_targeting_value_service_get_custom_targeting_value_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_targeting_value_service_get_custom_targeting_value_sync.py @@ -49,4 +49,5 @@ def sample_get_custom_targeting_value(): # Handle the response print(response) + # [END admanager_v1_generated_CustomTargetingValueService_GetCustomTargetingValue_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_targeting_value_service_list_custom_targeting_values_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_targeting_value_service_list_custom_targeting_values_sync.py index 219912ea4dd5..ba35980ef5dd 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_targeting_value_service_list_custom_targeting_values_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_custom_targeting_value_service_list_custom_targeting_values_sync.py @@ -50,4 +50,5 @@ def sample_list_custom_targeting_values(): for response in page_result: print(response) + # [END admanager_v1_generated_CustomTargetingValueService_ListCustomTargetingValues_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_device_capability_service_get_device_capability_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_device_capability_service_get_device_capability_sync.py new file mode 100644 index 000000000000..86a095ee50b8 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_device_capability_service_get_device_capability_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetDeviceCapability +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_DeviceCapabilityService_GetDeviceCapability_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_get_device_capability(): + # Create a client + client = admanager_v1.DeviceCapabilityServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetDeviceCapabilityRequest( + name="name_value", + ) + + # Make the request + response = client.get_device_capability(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_DeviceCapabilityService_GetDeviceCapability_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_device_capability_service_list_device_capabilities_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_device_capability_service_list_device_capabilities_sync.py new file mode 100644 index 000000000000..217c966cf7ad --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_device_capability_service_list_device_capabilities_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListDeviceCapabilities +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_DeviceCapabilityService_ListDeviceCapabilities_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_list_device_capabilities(): + # Create a client + client = admanager_v1.DeviceCapabilityServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListDeviceCapabilitiesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_device_capabilities(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END admanager_v1_generated_DeviceCapabilityService_ListDeviceCapabilities_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_device_category_service_get_device_category_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_device_category_service_get_device_category_sync.py index 2cfc4ebef9b1..896c1d30208d 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_device_category_service_get_device_category_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_device_category_service_get_device_category_sync.py @@ -49,4 +49,5 @@ def sample_get_device_category(): # Handle the response print(response) + # [END admanager_v1_generated_DeviceCategoryService_GetDeviceCategory_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_device_category_service_list_device_categories_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_device_category_service_list_device_categories_sync.py index 1f693176bf0b..72bec82471e0 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_device_category_service_list_device_categories_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_device_category_service_list_device_categories_sync.py @@ -50,4 +50,5 @@ def sample_list_device_categories(): for response in page_result: print(response) + # [END admanager_v1_generated_DeviceCategoryService_ListDeviceCategories_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_device_manufacturer_service_get_device_manufacturer_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_device_manufacturer_service_get_device_manufacturer_sync.py new file mode 100644 index 000000000000..7000a758e52a --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_device_manufacturer_service_get_device_manufacturer_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetDeviceManufacturer +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_DeviceManufacturerService_GetDeviceManufacturer_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_get_device_manufacturer(): + # Create a client + client = admanager_v1.DeviceManufacturerServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetDeviceManufacturerRequest( + name="name_value", + ) + + # Make the request + response = client.get_device_manufacturer(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_DeviceManufacturerService_GetDeviceManufacturer_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_device_manufacturer_service_list_device_manufacturers_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_device_manufacturer_service_list_device_manufacturers_sync.py new file mode 100644 index 000000000000..50413845fd92 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_device_manufacturer_service_list_device_manufacturers_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListDeviceManufacturers +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_DeviceManufacturerService_ListDeviceManufacturers_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_list_device_manufacturers(): + # Create a client + client = admanager_v1.DeviceManufacturerServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListDeviceManufacturersRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_device_manufacturers(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END admanager_v1_generated_DeviceManufacturerService_ListDeviceManufacturers_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_batch_create_entity_signals_mappings_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_batch_create_entity_signals_mappings_sync.py index 2118039a8a54..c391e97a97d6 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_batch_create_entity_signals_mappings_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_batch_create_entity_signals_mappings_sync.py @@ -54,4 +54,5 @@ def sample_batch_create_entity_signals_mappings(): # Handle the response print(response) + # [END admanager_v1_generated_EntitySignalsMappingService_BatchCreateEntitySignalsMappings_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_batch_update_entity_signals_mappings_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_batch_update_entity_signals_mappings_sync.py index f1206b06ecac..68258cd264cd 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_batch_update_entity_signals_mappings_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_batch_update_entity_signals_mappings_sync.py @@ -53,4 +53,5 @@ def sample_batch_update_entity_signals_mappings(): # Handle the response print(response) + # [END admanager_v1_generated_EntitySignalsMappingService_BatchUpdateEntitySignalsMappings_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_create_entity_signals_mapping_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_create_entity_signals_mapping_sync.py index b28c1d403914..ba9fba13d828 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_create_entity_signals_mapping_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_create_entity_signals_mapping_sync.py @@ -53,4 +53,5 @@ def sample_create_entity_signals_mapping(): # Handle the response print(response) + # [END admanager_v1_generated_EntitySignalsMappingService_CreateEntitySignalsMapping_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_get_entity_signals_mapping_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_get_entity_signals_mapping_sync.py index c6ff77655573..cb6bcac0dc42 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_get_entity_signals_mapping_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_get_entity_signals_mapping_sync.py @@ -49,4 +49,5 @@ def sample_get_entity_signals_mapping(): # Handle the response print(response) + # [END admanager_v1_generated_EntitySignalsMappingService_GetEntitySignalsMapping_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_list_entity_signals_mappings_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_list_entity_signals_mappings_sync.py index 4368604ea199..ca9d18919be3 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_list_entity_signals_mappings_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_list_entity_signals_mappings_sync.py @@ -50,4 +50,5 @@ def sample_list_entity_signals_mappings(): for response in page_result: print(response) + # [END admanager_v1_generated_EntitySignalsMappingService_ListEntitySignalsMappings_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_update_entity_signals_mapping_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_update_entity_signals_mapping_sync.py index b97e8e03f287..fbeb311c2aa2 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_update_entity_signals_mapping_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_entity_signals_mapping_service_update_entity_signals_mapping_sync.py @@ -52,4 +52,5 @@ def sample_update_entity_signals_mapping(): # Handle the response print(response) + # [END admanager_v1_generated_EntitySignalsMappingService_UpdateEntitySignalsMapping_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_geo_target_service_get_geo_target_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_geo_target_service_get_geo_target_sync.py index e93b4d9461c4..b8419e93639d 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_geo_target_service_get_geo_target_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_geo_target_service_get_geo_target_sync.py @@ -49,4 +49,5 @@ def sample_get_geo_target(): # Handle the response print(response) + # [END admanager_v1_generated_GeoTargetService_GetGeoTarget_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_geo_target_service_list_geo_targets_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_geo_target_service_list_geo_targets_sync.py index 363595119171..a0e1c50af9ae 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_geo_target_service_list_geo_targets_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_geo_target_service_list_geo_targets_sync.py @@ -50,4 +50,5 @@ def sample_list_geo_targets(): for response in page_result: print(response) + # [END admanager_v1_generated_GeoTargetService_ListGeoTargets_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_mobile_carrier_service_get_mobile_carrier_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_mobile_carrier_service_get_mobile_carrier_sync.py new file mode 100644 index 000000000000..b6aa96749e5e --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_mobile_carrier_service_get_mobile_carrier_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetMobileCarrier +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_MobileCarrierService_GetMobileCarrier_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_get_mobile_carrier(): + # Create a client + client = admanager_v1.MobileCarrierServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetMobileCarrierRequest( + name="name_value", + ) + + # Make the request + response = client.get_mobile_carrier(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_MobileCarrierService_GetMobileCarrier_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_mobile_carrier_service_list_mobile_carriers_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_mobile_carrier_service_list_mobile_carriers_sync.py new file mode 100644 index 000000000000..f80eec2ae700 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_mobile_carrier_service_list_mobile_carriers_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListMobileCarriers +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_MobileCarrierService_ListMobileCarriers_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_list_mobile_carriers(): + # Create a client + client = admanager_v1.MobileCarrierServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListMobileCarriersRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_mobile_carriers(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END admanager_v1_generated_MobileCarrierService_ListMobileCarriers_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_mobile_device_service_get_mobile_device_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_mobile_device_service_get_mobile_device_sync.py new file mode 100644 index 000000000000..340a5b5e9ad8 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_mobile_device_service_get_mobile_device_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetMobileDevice +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_MobileDeviceService_GetMobileDevice_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_get_mobile_device(): + # Create a client + client = admanager_v1.MobileDeviceServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetMobileDeviceRequest( + name="name_value", + ) + + # Make the request + response = client.get_mobile_device(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_MobileDeviceService_GetMobileDevice_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_mobile_device_service_list_mobile_devices_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_mobile_device_service_list_mobile_devices_sync.py new file mode 100644 index 000000000000..322414353c63 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_mobile_device_service_list_mobile_devices_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListMobileDevices +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_MobileDeviceService_ListMobileDevices_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_list_mobile_devices(): + # Create a client + client = admanager_v1.MobileDeviceServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListMobileDevicesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_mobile_devices(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END admanager_v1_generated_MobileDeviceService_ListMobileDevices_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_mobile_device_submodel_service_get_mobile_device_submodel_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_mobile_device_submodel_service_get_mobile_device_submodel_sync.py new file mode 100644 index 000000000000..3d6fb8ca5d98 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_mobile_device_submodel_service_get_mobile_device_submodel_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetMobileDeviceSubmodel +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_MobileDeviceSubmodelService_GetMobileDeviceSubmodel_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_get_mobile_device_submodel(): + # Create a client + client = admanager_v1.MobileDeviceSubmodelServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetMobileDeviceSubmodelRequest( + name="name_value", + ) + + # Make the request + response = client.get_mobile_device_submodel(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_MobileDeviceSubmodelService_GetMobileDeviceSubmodel_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_mobile_device_submodel_service_list_mobile_device_submodels_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_mobile_device_submodel_service_list_mobile_device_submodels_sync.py new file mode 100644 index 000000000000..d9c2905241ed --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_mobile_device_submodel_service_list_mobile_device_submodels_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListMobileDeviceSubmodels +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_MobileDeviceSubmodelService_ListMobileDeviceSubmodels_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_list_mobile_device_submodels(): + # Create a client + client = admanager_v1.MobileDeviceSubmodelServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListMobileDeviceSubmodelsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_mobile_device_submodels(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END admanager_v1_generated_MobileDeviceSubmodelService_ListMobileDeviceSubmodels_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_network_service_get_network_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_network_service_get_network_sync.py index d68e3cc87609..cf7a8faafb44 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_network_service_get_network_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_network_service_get_network_sync.py @@ -49,4 +49,5 @@ def sample_get_network(): # Handle the response print(response) + # [END admanager_v1_generated_NetworkService_GetNetwork_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_network_service_list_networks_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_network_service_list_networks_sync.py index 1490a27d922f..22d3ba562baa 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_network_service_list_networks_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_network_service_list_networks_sync.py @@ -39,8 +39,7 @@ def sample_list_networks(): client = admanager_v1.NetworkServiceClient() # Initialize request argument(s) - request = admanager_v1.ListNetworksRequest( - ) + request = admanager_v1.ListNetworksRequest() # Make the request response = client.list_networks(request=request) @@ -48,4 +47,5 @@ def sample_list_networks(): # Handle the response print(response) + # [END admanager_v1_generated_NetworkService_ListNetworks_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_operating_system_service_get_operating_system_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_operating_system_service_get_operating_system_sync.py index efa7d63cbad4..914c0b8fe9b5 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_operating_system_service_get_operating_system_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_operating_system_service_get_operating_system_sync.py @@ -49,4 +49,5 @@ def sample_get_operating_system(): # Handle the response print(response) + # [END admanager_v1_generated_OperatingSystemService_GetOperatingSystem_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_operating_system_service_list_operating_systems_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_operating_system_service_list_operating_systems_sync.py index 2795156aa71d..8704dc3bbddf 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_operating_system_service_list_operating_systems_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_operating_system_service_list_operating_systems_sync.py @@ -50,4 +50,5 @@ def sample_list_operating_systems(): for response in page_result: print(response) + # [END admanager_v1_generated_OperatingSystemService_ListOperatingSystems_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_operating_system_version_service_get_operating_system_version_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_operating_system_version_service_get_operating_system_version_sync.py index 4ed443889583..80dc98925344 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_operating_system_version_service_get_operating_system_version_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_operating_system_version_service_get_operating_system_version_sync.py @@ -49,4 +49,5 @@ def sample_get_operating_system_version(): # Handle the response print(response) + # [END admanager_v1_generated_OperatingSystemVersionService_GetOperatingSystemVersion_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_operating_system_version_service_list_operating_system_versions_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_operating_system_version_service_list_operating_system_versions_sync.py index 4d3a37402329..8201de175157 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_operating_system_version_service_list_operating_system_versions_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_operating_system_version_service_list_operating_system_versions_sync.py @@ -50,4 +50,5 @@ def sample_list_operating_system_versions(): for response in page_result: print(response) + # [END admanager_v1_generated_OperatingSystemVersionService_ListOperatingSystemVersions_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_order_service_get_order_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_order_service_get_order_sync.py index 5c541f74f79c..d3c2644fd8a3 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_order_service_get_order_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_order_service_get_order_sync.py @@ -49,4 +49,5 @@ def sample_get_order(): # Handle the response print(response) + # [END admanager_v1_generated_OrderService_GetOrder_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_order_service_list_orders_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_order_service_list_orders_sync.py index 983c77167482..6e945f910922 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_order_service_list_orders_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_order_service_list_orders_sync.py @@ -50,4 +50,5 @@ def sample_list_orders(): for response in page_result: print(response) + # [END admanager_v1_generated_OrderService_ListOrders_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_batch_activate_placements_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_batch_activate_placements_sync.py new file mode 100644 index 000000000000..4ee37ae66365 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_batch_activate_placements_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchActivatePlacements +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_PlacementService_BatchActivatePlacements_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_batch_activate_placements(): + # Create a client + client = admanager_v1.PlacementServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchActivatePlacementsRequest( + parent="parent_value", + names=["names_value1", "names_value2"], + ) + + # Make the request + response = client.batch_activate_placements(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_PlacementService_BatchActivatePlacements_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_batch_archive_placements_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_batch_archive_placements_sync.py new file mode 100644 index 000000000000..f34114e1ba0c --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_batch_archive_placements_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchArchivePlacements +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_PlacementService_BatchArchivePlacements_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_batch_archive_placements(): + # Create a client + client = admanager_v1.PlacementServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchArchivePlacementsRequest( + parent="parent_value", + names=["names_value1", "names_value2"], + ) + + # Make the request + response = client.batch_archive_placements(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_PlacementService_BatchArchivePlacements_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_batch_create_placements_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_batch_create_placements_sync.py new file mode 100644 index 000000000000..ee5d355b4eca --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_batch_create_placements_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchCreatePlacements +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_PlacementService_BatchCreatePlacements_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_batch_create_placements(): + # Create a client + client = admanager_v1.PlacementServiceClient() + + # Initialize request argument(s) + requests = admanager_v1.CreatePlacementRequest() + requests.parent = "parent_value" + + request = admanager_v1.BatchCreatePlacementsRequest( + parent="parent_value", + requests=requests, + ) + + # Make the request + response = client.batch_create_placements(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_PlacementService_BatchCreatePlacements_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_batch_deactivate_placements_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_batch_deactivate_placements_sync.py new file mode 100644 index 000000000000..f32225482f8c --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_batch_deactivate_placements_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchDeactivatePlacements +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_PlacementService_BatchDeactivatePlacements_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_batch_deactivate_placements(): + # Create a client + client = admanager_v1.PlacementServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchDeactivatePlacementsRequest( + parent="parent_value", + names=["names_value1", "names_value2"], + ) + + # Make the request + response = client.batch_deactivate_placements(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_PlacementService_BatchDeactivatePlacements_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_batch_update_placements_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_batch_update_placements_sync.py new file mode 100644 index 000000000000..5746bf3c7ac3 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_batch_update_placements_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchUpdatePlacements +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_PlacementService_BatchUpdatePlacements_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_batch_update_placements(): + # Create a client + client = admanager_v1.PlacementServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchUpdatePlacementsRequest( + parent="parent_value", + ) + + # Make the request + response = client.batch_update_placements(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_PlacementService_BatchUpdatePlacements_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_create_placement_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_create_placement_sync.py new file mode 100644 index 000000000000..fd049a31b149 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_create_placement_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreatePlacement +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_PlacementService_CreatePlacement_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_create_placement(): + # Create a client + client = admanager_v1.PlacementServiceClient() + + # Initialize request argument(s) + request = admanager_v1.CreatePlacementRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_placement(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_PlacementService_CreatePlacement_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_get_placement_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_get_placement_sync.py index df156516499d..0e7cb6ea0066 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_get_placement_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_get_placement_sync.py @@ -49,4 +49,5 @@ def sample_get_placement(): # Handle the response print(response) + # [END admanager_v1_generated_PlacementService_GetPlacement_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_list_placements_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_list_placements_sync.py index 50ba80625904..cfe830fc4e0d 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_list_placements_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_list_placements_sync.py @@ -50,4 +50,5 @@ def sample_list_placements(): for response in page_result: print(response) + # [END admanager_v1_generated_PlacementService_ListPlacements_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_update_placement_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_update_placement_sync.py new file mode 100644 index 000000000000..8d4d3bfb74b8 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_placement_service_update_placement_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdatePlacement +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_PlacementService_UpdatePlacement_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_update_placement(): + # Create a client + client = admanager_v1.PlacementServiceClient() + + # Initialize request argument(s) + request = admanager_v1.UpdatePlacementRequest() + + # Make the request + response = client.update_placement(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_PlacementService_UpdatePlacement_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_deal_service_create_private_auction_deal_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_deal_service_create_private_auction_deal_sync.py index 938059fe62db..7f8e79611a13 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_deal_service_create_private_auction_deal_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_deal_service_create_private_auction_deal_sync.py @@ -49,4 +49,5 @@ def sample_create_private_auction_deal(): # Handle the response print(response) + # [END admanager_v1_generated_PrivateAuctionDealService_CreatePrivateAuctionDeal_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_deal_service_get_private_auction_deal_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_deal_service_get_private_auction_deal_sync.py index 0b0c0647d7ce..baf0420597cd 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_deal_service_get_private_auction_deal_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_deal_service_get_private_auction_deal_sync.py @@ -49,4 +49,5 @@ def sample_get_private_auction_deal(): # Handle the response print(response) + # [END admanager_v1_generated_PrivateAuctionDealService_GetPrivateAuctionDeal_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_deal_service_list_private_auction_deals_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_deal_service_list_private_auction_deals_sync.py index 71381259f9af..c4134a65435b 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_deal_service_list_private_auction_deals_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_deal_service_list_private_auction_deals_sync.py @@ -50,4 +50,5 @@ def sample_list_private_auction_deals(): for response in page_result: print(response) + # [END admanager_v1_generated_PrivateAuctionDealService_ListPrivateAuctionDeals_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_deal_service_update_private_auction_deal_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_deal_service_update_private_auction_deal_sync.py index b98860572289..199911aad75a 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_deal_service_update_private_auction_deal_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_deal_service_update_private_auction_deal_sync.py @@ -39,8 +39,7 @@ def sample_update_private_auction_deal(): client = admanager_v1.PrivateAuctionDealServiceClient() # Initialize request argument(s) - request = admanager_v1.UpdatePrivateAuctionDealRequest( - ) + request = admanager_v1.UpdatePrivateAuctionDealRequest() # Make the request response = client.update_private_auction_deal(request=request) @@ -48,4 +47,5 @@ def sample_update_private_auction_deal(): # Handle the response print(response) + # [END admanager_v1_generated_PrivateAuctionDealService_UpdatePrivateAuctionDeal_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_service_create_private_auction_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_service_create_private_auction_sync.py index d31e2cf11447..6ebcb8ad5ed5 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_service_create_private_auction_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_service_create_private_auction_sync.py @@ -49,4 +49,5 @@ def sample_create_private_auction(): # Handle the response print(response) + # [END admanager_v1_generated_PrivateAuctionService_CreatePrivateAuction_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_service_get_private_auction_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_service_get_private_auction_sync.py index a3d0b8a8d384..6b038930acac 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_service_get_private_auction_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_service_get_private_auction_sync.py @@ -49,4 +49,5 @@ def sample_get_private_auction(): # Handle the response print(response) + # [END admanager_v1_generated_PrivateAuctionService_GetPrivateAuction_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_service_list_private_auctions_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_service_list_private_auctions_sync.py index fd82a1cde26e..5a7abf8284b2 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_service_list_private_auctions_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_service_list_private_auctions_sync.py @@ -50,4 +50,5 @@ def sample_list_private_auctions(): for response in page_result: print(response) + # [END admanager_v1_generated_PrivateAuctionService_ListPrivateAuctions_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_service_update_private_auction_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_service_update_private_auction_sync.py index a0e6eb49dcd0..1b62b3160030 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_service_update_private_auction_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_private_auction_service_update_private_auction_sync.py @@ -39,8 +39,7 @@ def sample_update_private_auction(): client = admanager_v1.PrivateAuctionServiceClient() # Initialize request argument(s) - request = admanager_v1.UpdatePrivateAuctionRequest( - ) + request = admanager_v1.UpdatePrivateAuctionRequest() # Make the request response = client.update_private_auction(request=request) @@ -48,4 +47,5 @@ def sample_update_private_auction(): # Handle the response print(response) + # [END admanager_v1_generated_PrivateAuctionService_UpdatePrivateAuction_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_programmatic_buyer_service_get_programmatic_buyer_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_programmatic_buyer_service_get_programmatic_buyer_sync.py index a82393418564..25c5bd7bff46 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_programmatic_buyer_service_get_programmatic_buyer_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_programmatic_buyer_service_get_programmatic_buyer_sync.py @@ -49,4 +49,5 @@ def sample_get_programmatic_buyer(): # Handle the response print(response) + # [END admanager_v1_generated_ProgrammaticBuyerService_GetProgrammaticBuyer_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_programmatic_buyer_service_list_programmatic_buyers_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_programmatic_buyer_service_list_programmatic_buyers_sync.py index b807ed3ae08e..856f69ad3df3 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_programmatic_buyer_service_list_programmatic_buyers_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_programmatic_buyer_service_list_programmatic_buyers_sync.py @@ -50,4 +50,5 @@ def sample_list_programmatic_buyers(): for response in page_result: print(response) + # [END admanager_v1_generated_ProgrammaticBuyerService_ListProgrammaticBuyers_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_create_report_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_create_report_sync.py index 8424f2b1ec6e..807940412bb4 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_create_report_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_create_report_sync.py @@ -40,9 +40,9 @@ def sample_create_report(): # Initialize request argument(s) report = admanager_v1.Report() - report.report_definition.dimensions = ['CUSTOM_DIMENSION_9_VALUE'] - report.report_definition.metrics = ['YIELD_GROUP_SUCCESSFUL_RESPONSES'] - report.report_definition.report_type = "HISTORICAL" + report.report_definition.dimensions = ["CUSTOM_DIMENSION_9_VALUE"] + report.report_definition.metrics = ["YIELD_GROUP_SUCCESSFUL_RESPONSES"] + report.report_definition.report_type = "AD_SPEED" request = admanager_v1.CreateReportRequest( parent="parent_value", @@ -55,4 +55,5 @@ def sample_create_report(): # Handle the response print(response) + # [END admanager_v1_generated_ReportService_CreateReport_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_fetch_report_result_rows_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_fetch_report_result_rows_sync.py index afda51cac705..7d421ec4ce32 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_fetch_report_result_rows_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_fetch_report_result_rows_sync.py @@ -39,8 +39,7 @@ def sample_fetch_report_result_rows(): client = admanager_v1.ReportServiceClient() # Initialize request argument(s) - request = admanager_v1.FetchReportResultRowsRequest( - ) + request = admanager_v1.FetchReportResultRowsRequest() # Make the request page_result = client.fetch_report_result_rows(request=request) @@ -49,4 +48,5 @@ def sample_fetch_report_result_rows(): for response in page_result: print(response) + # [END admanager_v1_generated_ReportService_FetchReportResultRows_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_get_report_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_get_report_sync.py index 75b4e3d097fb..7b43e6f1b788 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_get_report_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_get_report_sync.py @@ -49,4 +49,5 @@ def sample_get_report(): # Handle the response print(response) + # [END admanager_v1_generated_ReportService_GetReport_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_list_reports_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_list_reports_sync.py index 23aa943b05a8..c6a5fdbff600 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_list_reports_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_list_reports_sync.py @@ -50,4 +50,5 @@ def sample_list_reports(): for response in page_result: print(response) + # [END admanager_v1_generated_ReportService_ListReports_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_run_report_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_run_report_sync.py index 6119fe193e0b..f11bd97b420d 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_run_report_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_run_report_sync.py @@ -53,4 +53,5 @@ def sample_run_report(): # Handle the response print(response) + # [END admanager_v1_generated_ReportService_RunReport_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_update_report_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_update_report_sync.py index 8fe3768e2821..2aadb0389450 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_update_report_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_report_service_update_report_sync.py @@ -40,9 +40,9 @@ def sample_update_report(): # Initialize request argument(s) report = admanager_v1.Report() - report.report_definition.dimensions = ['CUSTOM_DIMENSION_9_VALUE'] - report.report_definition.metrics = ['YIELD_GROUP_SUCCESSFUL_RESPONSES'] - report.report_definition.report_type = "HISTORICAL" + report.report_definition.dimensions = ["CUSTOM_DIMENSION_9_VALUE"] + report.report_definition.metrics = ["YIELD_GROUP_SUCCESSFUL_RESPONSES"] + report.report_definition.report_type = "AD_SPEED" request = admanager_v1.UpdateReportRequest( report=report, @@ -54,4 +54,5 @@ def sample_update_report(): # Handle the response print(response) + # [END admanager_v1_generated_ReportService_UpdateReport_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_role_service_get_role_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_role_service_get_role_sync.py index 5667f7249bc7..3acc3e7d4472 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_role_service_get_role_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_role_service_get_role_sync.py @@ -49,4 +49,5 @@ def sample_get_role(): # Handle the response print(response) + # [END admanager_v1_generated_RoleService_GetRole_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_role_service_list_roles_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_role_service_list_roles_sync.py index 1c388b9e1286..c35ff6da9635 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_role_service_list_roles_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_role_service_list_roles_sync.py @@ -50,4 +50,5 @@ def sample_list_roles(): for response in page_result: print(response) + # [END admanager_v1_generated_RoleService_ListRoles_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_batch_create_sites_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_batch_create_sites_sync.py new file mode 100644 index 000000000000..ae5a541e1340 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_batch_create_sites_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchCreateSites +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_SiteService_BatchCreateSites_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_batch_create_sites(): + # Create a client + client = admanager_v1.SiteServiceClient() + + # Initialize request argument(s) + requests = admanager_v1.CreateSiteRequest() + requests.parent = "parent_value" + + request = admanager_v1.BatchCreateSitesRequest( + parent="parent_value", + requests=requests, + ) + + # Make the request + response = client.batch_create_sites(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_SiteService_BatchCreateSites_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_batch_deactivate_sites_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_batch_deactivate_sites_sync.py new file mode 100644 index 000000000000..0f2a5409a415 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_batch_deactivate_sites_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchDeactivateSites +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_SiteService_BatchDeactivateSites_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_batch_deactivate_sites(): + # Create a client + client = admanager_v1.SiteServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchDeactivateSitesRequest( + parent="parent_value", + names=["names_value1", "names_value2"], + ) + + # Make the request + response = client.batch_deactivate_sites(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_SiteService_BatchDeactivateSites_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_batch_submit_sites_for_approval_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_batch_submit_sites_for_approval_sync.py new file mode 100644 index 000000000000..b46f1f091ee9 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_batch_submit_sites_for_approval_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchSubmitSitesForApproval +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_SiteService_BatchSubmitSitesForApproval_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_batch_submit_sites_for_approval(): + # Create a client + client = admanager_v1.SiteServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchSubmitSitesForApprovalRequest( + parent="parent_value", + names=["names_value1", "names_value2"], + ) + + # Make the request + response = client.batch_submit_sites_for_approval(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_SiteService_BatchSubmitSitesForApproval_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_batch_update_sites_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_batch_update_sites_sync.py new file mode 100644 index 000000000000..89439064a4ff --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_batch_update_sites_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchUpdateSites +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_SiteService_BatchUpdateSites_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_batch_update_sites(): + # Create a client + client = admanager_v1.SiteServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchUpdateSitesRequest( + parent="parent_value", + ) + + # Make the request + response = client.batch_update_sites(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_SiteService_BatchUpdateSites_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_create_site_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_create_site_sync.py new file mode 100644 index 000000000000..8e0c13488c29 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_create_site_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateSite +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_SiteService_CreateSite_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_create_site(): + # Create a client + client = admanager_v1.SiteServiceClient() + + # Initialize request argument(s) + request = admanager_v1.CreateSiteRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_site(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_SiteService_CreateSite_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_get_site_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_get_site_sync.py new file mode 100644 index 000000000000..56f3627e327f --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_get_site_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetSite +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_SiteService_GetSite_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_get_site(): + # Create a client + client = admanager_v1.SiteServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetSiteRequest( + name="name_value", + ) + + # Make the request + response = client.get_site(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_SiteService_GetSite_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_list_sites_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_list_sites_sync.py new file mode 100644 index 000000000000..b53856552767 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_list_sites_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListSites +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_SiteService_ListSites_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_list_sites(): + # Create a client + client = admanager_v1.SiteServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListSitesRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_sites(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END admanager_v1_generated_SiteService_ListSites_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_update_site_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_update_site_sync.py new file mode 100644 index 000000000000..735dfb9bad86 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_site_service_update_site_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateSite +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_SiteService_UpdateSite_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_update_site(): + # Create a client + client = admanager_v1.SiteServiceClient() + + # Initialize request argument(s) + request = admanager_v1.UpdateSiteRequest() + + # Make the request + response = client.update_site(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_SiteService_UpdateSite_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_taxonomy_category_service_get_taxonomy_category_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_taxonomy_category_service_get_taxonomy_category_sync.py index b6f8f12a52e7..64d369345a2f 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_taxonomy_category_service_get_taxonomy_category_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_taxonomy_category_service_get_taxonomy_category_sync.py @@ -49,4 +49,5 @@ def sample_get_taxonomy_category(): # Handle the response print(response) + # [END admanager_v1_generated_TaxonomyCategoryService_GetTaxonomyCategory_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_taxonomy_category_service_list_taxonomy_categories_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_taxonomy_category_service_list_taxonomy_categories_sync.py index ca5a0308c5de..9e61856fa474 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_taxonomy_category_service_list_taxonomy_categories_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_taxonomy_category_service_list_taxonomy_categories_sync.py @@ -50,4 +50,5 @@ def sample_list_taxonomy_categories(): for response in page_result: print(response) + # [END admanager_v1_generated_TaxonomyCategoryService_ListTaxonomyCategories_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_batch_activate_teams_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_batch_activate_teams_sync.py new file mode 100644 index 000000000000..9599a03465b3 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_batch_activate_teams_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchActivateTeams +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_TeamService_BatchActivateTeams_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_batch_activate_teams(): + # Create a client + client = admanager_v1.TeamServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchActivateTeamsRequest( + parent="parent_value", + names=["names_value1", "names_value2"], + ) + + # Make the request + response = client.batch_activate_teams(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_TeamService_BatchActivateTeams_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_batch_create_teams_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_batch_create_teams_sync.py new file mode 100644 index 000000000000..dbaff4008a5b --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_batch_create_teams_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchCreateTeams +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_TeamService_BatchCreateTeams_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_batch_create_teams(): + # Create a client + client = admanager_v1.TeamServiceClient() + + # Initialize request argument(s) + requests = admanager_v1.CreateTeamRequest() + requests.parent = "parent_value" + + request = admanager_v1.BatchCreateTeamsRequest( + parent="parent_value", + requests=requests, + ) + + # Make the request + response = client.batch_create_teams(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_TeamService_BatchCreateTeams_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_batch_deactivate_teams_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_batch_deactivate_teams_sync.py new file mode 100644 index 000000000000..c0b942f0aa9e --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_batch_deactivate_teams_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchDeactivateTeams +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_TeamService_BatchDeactivateTeams_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_batch_deactivate_teams(): + # Create a client + client = admanager_v1.TeamServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchDeactivateTeamsRequest( + parent="parent_value", + names=["names_value1", "names_value2"], + ) + + # Make the request + response = client.batch_deactivate_teams(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_TeamService_BatchDeactivateTeams_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_batch_update_teams_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_batch_update_teams_sync.py new file mode 100644 index 000000000000..fb1b8fafdc5d --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_batch_update_teams_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BatchUpdateTeams +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_TeamService_BatchUpdateTeams_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_batch_update_teams(): + # Create a client + client = admanager_v1.TeamServiceClient() + + # Initialize request argument(s) + request = admanager_v1.BatchUpdateTeamsRequest( + parent="parent_value", + ) + + # Make the request + response = client.batch_update_teams(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_TeamService_BatchUpdateTeams_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_create_team_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_create_team_sync.py new file mode 100644 index 000000000000..a0883772492f --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_create_team_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateTeam +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_TeamService_CreateTeam_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_create_team(): + # Create a client + client = admanager_v1.TeamServiceClient() + + # Initialize request argument(s) + request = admanager_v1.CreateTeamRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_team(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_TeamService_CreateTeam_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_get_team_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_get_team_sync.py new file mode 100644 index 000000000000..6c0389bf0a03 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_get_team_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetTeam +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_TeamService_GetTeam_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_get_team(): + # Create a client + client = admanager_v1.TeamServiceClient() + + # Initialize request argument(s) + request = admanager_v1.GetTeamRequest( + name="name_value", + ) + + # Make the request + response = client.get_team(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_TeamService_GetTeam_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_list_teams_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_list_teams_sync.py new file mode 100644 index 000000000000..e4e682685bb2 --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_list_teams_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListTeams +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_TeamService_ListTeams_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_list_teams(): + # Create a client + client = admanager_v1.TeamServiceClient() + + # Initialize request argument(s) + request = admanager_v1.ListTeamsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_teams(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END admanager_v1_generated_TeamService_ListTeams_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_update_team_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_update_team_sync.py new file mode 100644 index 000000000000..8deda3831cea --- /dev/null +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_team_service_update_team_sync.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateTeam +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-ads-admanager + + +# [START admanager_v1_generated_TeamService_UpdateTeam_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.ads import admanager_v1 + + +def sample_update_team(): + # Create a client + client = admanager_v1.TeamServiceClient() + + # Initialize request argument(s) + request = admanager_v1.UpdateTeamRequest() + + # Make the request + response = client.update_team(request=request) + + # Handle the response + print(response) + + +# [END admanager_v1_generated_TeamService_UpdateTeam_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_user_service_get_user_sync.py b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_user_service_get_user_sync.py index cdca4be3d619..fd229025021a 100644 --- a/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_user_service_get_user_sync.py +++ b/packages/google-ads-admanager/samples/generated_samples/admanager_v1_generated_user_service_get_user_sync.py @@ -49,4 +49,5 @@ def sample_get_user(): # Handle the response print(response) + # [END admanager_v1_generated_UserService_GetUser_sync] diff --git a/packages/google-ads-admanager/samples/generated_samples/snippet_metadata_google.ads.admanager.v1.json b/packages/google-ads-admanager/samples/generated_samples/snippet_metadata_google.ads.admanager.v1.json index ef4b8a9ebe57..a4af384532a3 100644 --- a/packages/google-ads-admanager/samples/generated_samples/snippet_metadata_google.ads.admanager.v1.json +++ b/packages/google-ads-admanager/samples/generated_samples/snippet_metadata_google.ads.admanager.v1.json @@ -420,25 +420,25 @@ "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.AdUnitServiceClient", - "shortName": "AdUnitServiceClient" + "fullName": "google.ads.admanager_v1.AdReviewCenterAdServiceClient", + "shortName": "AdReviewCenterAdServiceClient" }, - "fullName": "google.ads.admanager_v1.AdUnitServiceClient.get_ad_unit", + "fullName": "google.ads.admanager_v1.AdReviewCenterAdServiceClient.batch_allow_ad_review_center_ads", "method": { - "fullName": "google.ads.admanager.v1.AdUnitService.GetAdUnit", + "fullName": "google.ads.admanager.v1.AdReviewCenterAdService.BatchAllowAdReviewCenterAds", "service": { - "fullName": "google.ads.admanager.v1.AdUnitService", - "shortName": "AdUnitService" + "fullName": "google.ads.admanager.v1.AdReviewCenterAdService", + "shortName": "AdReviewCenterAdService" }, - "shortName": "GetAdUnit" + "shortName": "BatchAllowAdReviewCenterAds" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.GetAdUnitRequest" + "type": "google.ads.admanager_v1.types.BatchAllowAdReviewCenterAdsRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -454,22 +454,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.AdUnit", - "shortName": "get_ad_unit" + "resultType": "google.api_core.operation.Operation", + "shortName": "batch_allow_ad_review_center_ads" }, - "description": "Sample for GetAdUnit", - "file": "admanager_v1_generated_ad_unit_service_get_ad_unit_sync.py", + "description": "Sample for BatchAllowAdReviewCenterAds", + "file": "admanager_v1_generated_ad_review_center_ad_service_batch_allow_ad_review_center_ads_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_AdUnitService_GetAdUnit_sync", + "regionTag": "admanager_v1_generated_AdReviewCenterAdService_BatchAllowAdReviewCenterAds_sync", "segments": [ { - "end": 51, + "end": 56, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 56, "start": 27, "type": "SHORT" }, @@ -479,43 +479,43 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 46, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 53, + "start": 47, "type": "REQUEST_EXECUTION" }, { - "end": 52, - "start": 49, + "end": 57, + "start": 54, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_ad_unit_service_get_ad_unit_sync.py" + "title": "admanager_v1_generated_ad_review_center_ad_service_batch_allow_ad_review_center_ads_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.AdUnitServiceClient", - "shortName": "AdUnitServiceClient" + "fullName": "google.ads.admanager_v1.AdReviewCenterAdServiceClient", + "shortName": "AdReviewCenterAdServiceClient" }, - "fullName": "google.ads.admanager_v1.AdUnitServiceClient.list_ad_unit_sizes", + "fullName": "google.ads.admanager_v1.AdReviewCenterAdServiceClient.batch_block_ad_review_center_ads", "method": { - "fullName": "google.ads.admanager.v1.AdUnitService.ListAdUnitSizes", + "fullName": "google.ads.admanager.v1.AdReviewCenterAdService.BatchBlockAdReviewCenterAds", "service": { - "fullName": "google.ads.admanager.v1.AdUnitService", - "shortName": "AdUnitService" + "fullName": "google.ads.admanager.v1.AdReviewCenterAdService", + "shortName": "AdReviewCenterAdService" }, - "shortName": "ListAdUnitSizes" + "shortName": "BatchBlockAdReviewCenterAds" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.ListAdUnitSizesRequest" + "type": "google.ads.admanager_v1.types.BatchBlockAdReviewCenterAdsRequest" }, { "name": "parent", @@ -534,22 +534,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.services.ad_unit_service.pagers.ListAdUnitSizesPager", - "shortName": "list_ad_unit_sizes" + "resultType": "google.api_core.operation.Operation", + "shortName": "batch_block_ad_review_center_ads" }, - "description": "Sample for ListAdUnitSizes", - "file": "admanager_v1_generated_ad_unit_service_list_ad_unit_sizes_sync.py", + "description": "Sample for BatchBlockAdReviewCenterAds", + "file": "admanager_v1_generated_ad_review_center_ad_service_batch_block_ad_review_center_ads_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_AdUnitService_ListAdUnitSizes_sync", + "regionTag": "admanager_v1_generated_AdReviewCenterAdService_BatchBlockAdReviewCenterAds_sync", "segments": [ { - "end": 52, + "end": 56, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 56, "start": 27, "type": "SHORT" }, @@ -559,43 +559,43 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 46, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 53, + "start": 47, "type": "REQUEST_EXECUTION" }, { - "end": 53, - "start": 49, + "end": 57, + "start": 54, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_ad_unit_service_list_ad_unit_sizes_sync.py" + "title": "admanager_v1_generated_ad_review_center_ad_service_batch_block_ad_review_center_ads_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.AdUnitServiceClient", - "shortName": "AdUnitServiceClient" + "fullName": "google.ads.admanager_v1.AdReviewCenterAdServiceClient", + "shortName": "AdReviewCenterAdServiceClient" }, - "fullName": "google.ads.admanager_v1.AdUnitServiceClient.list_ad_units", + "fullName": "google.ads.admanager_v1.AdReviewCenterAdServiceClient.search_ad_review_center_ads", "method": { - "fullName": "google.ads.admanager.v1.AdUnitService.ListAdUnits", + "fullName": "google.ads.admanager.v1.AdReviewCenterAdService.SearchAdReviewCenterAds", "service": { - "fullName": "google.ads.admanager.v1.AdUnitService", - "shortName": "AdUnitService" + "fullName": "google.ads.admanager.v1.AdReviewCenterAdService", + "shortName": "AdReviewCenterAdService" }, - "shortName": "ListAdUnits" + "shortName": "SearchAdReviewCenterAds" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.ListAdUnitsRequest" + "type": "google.ads.admanager_v1.types.SearchAdReviewCenterAdsRequest" }, { "name": "parent", @@ -614,22 +614,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.services.ad_unit_service.pagers.ListAdUnitsPager", - "shortName": "list_ad_units" + "resultType": "google.ads.admanager_v1.services.ad_review_center_ad_service.pagers.SearchAdReviewCenterAdsPager", + "shortName": "search_ad_review_center_ads" }, - "description": "Sample for ListAdUnits", - "file": "admanager_v1_generated_ad_unit_service_list_ad_units_sync.py", + "description": "Sample for SearchAdReviewCenterAds", + "file": "admanager_v1_generated_ad_review_center_ad_service_search_ad_review_center_ads_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_AdUnitService_ListAdUnits_sync", + "regionTag": "admanager_v1_generated_AdReviewCenterAdService_SearchAdReviewCenterAds_sync", "segments": [ { - "end": 52, + "end": 53, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 53, "start": 27, "type": "SHORT" }, @@ -639,43 +639,43 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 46, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 49, + "start": 47, "type": "REQUEST_EXECUTION" }, { - "end": 53, - "start": 49, + "end": 54, + "start": 50, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_ad_unit_service_list_ad_units_sync.py" + "title": "admanager_v1_generated_ad_review_center_ad_service_search_ad_review_center_ads_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.BandwidthGroupServiceClient", - "shortName": "BandwidthGroupServiceClient" + "fullName": "google.ads.admanager_v1.AdUnitServiceClient", + "shortName": "AdUnitServiceClient" }, - "fullName": "google.ads.admanager_v1.BandwidthGroupServiceClient.get_bandwidth_group", + "fullName": "google.ads.admanager_v1.AdUnitServiceClient.get_ad_unit", "method": { - "fullName": "google.ads.admanager.v1.BandwidthGroupService.GetBandwidthGroup", + "fullName": "google.ads.admanager.v1.AdUnitService.GetAdUnit", "service": { - "fullName": "google.ads.admanager.v1.BandwidthGroupService", - "shortName": "BandwidthGroupService" + "fullName": "google.ads.admanager.v1.AdUnitService", + "shortName": "AdUnitService" }, - "shortName": "GetBandwidthGroup" + "shortName": "GetAdUnit" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.GetBandwidthGroupRequest" + "type": "google.ads.admanager_v1.types.GetAdUnitRequest" }, { "name": "name", @@ -694,14 +694,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.BandwidthGroup", - "shortName": "get_bandwidth_group" + "resultType": "google.ads.admanager_v1.types.AdUnit", + "shortName": "get_ad_unit" }, - "description": "Sample for GetBandwidthGroup", - "file": "admanager_v1_generated_bandwidth_group_service_get_bandwidth_group_sync.py", + "description": "Sample for GetAdUnit", + "file": "admanager_v1_generated_ad_unit_service_get_ad_unit_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_BandwidthGroupService_GetBandwidthGroup_sync", + "regionTag": "admanager_v1_generated_AdUnitService_GetAdUnit_sync", "segments": [ { "end": 51, @@ -734,28 +734,28 @@ "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_bandwidth_group_service_get_bandwidth_group_sync.py" + "title": "admanager_v1_generated_ad_unit_service_get_ad_unit_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.BandwidthGroupServiceClient", - "shortName": "BandwidthGroupServiceClient" + "fullName": "google.ads.admanager_v1.AdUnitServiceClient", + "shortName": "AdUnitServiceClient" }, - "fullName": "google.ads.admanager_v1.BandwidthGroupServiceClient.list_bandwidth_groups", + "fullName": "google.ads.admanager_v1.AdUnitServiceClient.list_ad_unit_sizes", "method": { - "fullName": "google.ads.admanager.v1.BandwidthGroupService.ListBandwidthGroups", + "fullName": "google.ads.admanager.v1.AdUnitService.ListAdUnitSizes", "service": { - "fullName": "google.ads.admanager.v1.BandwidthGroupService", - "shortName": "BandwidthGroupService" + "fullName": "google.ads.admanager.v1.AdUnitService", + "shortName": "AdUnitService" }, - "shortName": "ListBandwidthGroups" + "shortName": "ListAdUnitSizes" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.ListBandwidthGroupsRequest" + "type": "google.ads.admanager_v1.types.ListAdUnitSizesRequest" }, { "name": "parent", @@ -774,14 +774,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.services.bandwidth_group_service.pagers.ListBandwidthGroupsPager", - "shortName": "list_bandwidth_groups" + "resultType": "google.ads.admanager_v1.services.ad_unit_service.pagers.ListAdUnitSizesPager", + "shortName": "list_ad_unit_sizes" }, - "description": "Sample for ListBandwidthGroups", - "file": "admanager_v1_generated_bandwidth_group_service_list_bandwidth_groups_sync.py", + "description": "Sample for ListAdUnitSizes", + "file": "admanager_v1_generated_ad_unit_service_list_ad_unit_sizes_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_BandwidthGroupService_ListBandwidthGroups_sync", + "regionTag": "admanager_v1_generated_AdUnitService_ListAdUnitSizes_sync", "segments": [ { "end": 52, @@ -814,31 +814,31 @@ "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_bandwidth_group_service_list_bandwidth_groups_sync.py" + "title": "admanager_v1_generated_ad_unit_service_list_ad_unit_sizes_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.CompanyServiceClient", - "shortName": "CompanyServiceClient" + "fullName": "google.ads.admanager_v1.AdUnitServiceClient", + "shortName": "AdUnitServiceClient" }, - "fullName": "google.ads.admanager_v1.CompanyServiceClient.get_company", + "fullName": "google.ads.admanager_v1.AdUnitServiceClient.list_ad_units", "method": { - "fullName": "google.ads.admanager.v1.CompanyService.GetCompany", + "fullName": "google.ads.admanager.v1.AdUnitService.ListAdUnits", "service": { - "fullName": "google.ads.admanager.v1.CompanyService", - "shortName": "CompanyService" + "fullName": "google.ads.admanager.v1.AdUnitService", + "shortName": "AdUnitService" }, - "shortName": "GetCompany" + "shortName": "ListAdUnits" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.GetCompanyRequest" + "type": "google.ads.admanager_v1.types.ListAdUnitsRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -854,22 +854,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.Company", - "shortName": "get_company" + "resultType": "google.ads.admanager_v1.services.ad_unit_service.pagers.ListAdUnitsPager", + "shortName": "list_ad_units" }, - "description": "Sample for GetCompany", - "file": "admanager_v1_generated_company_service_get_company_sync.py", + "description": "Sample for ListAdUnits", + "file": "admanager_v1_generated_ad_unit_service_list_ad_units_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_CompanyService_GetCompany_sync", + "regionTag": "admanager_v1_generated_AdUnitService_ListAdUnits_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -889,36 +889,36 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_company_service_get_company_sync.py" + "title": "admanager_v1_generated_ad_unit_service_list_ad_units_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.CompanyServiceClient", - "shortName": "CompanyServiceClient" + "fullName": "google.ads.admanager_v1.ApplicationServiceClient", + "shortName": "ApplicationServiceClient" }, - "fullName": "google.ads.admanager_v1.CompanyServiceClient.list_companies", + "fullName": "google.ads.admanager_v1.ApplicationServiceClient.get_application", "method": { - "fullName": "google.ads.admanager.v1.CompanyService.ListCompanies", + "fullName": "google.ads.admanager.v1.ApplicationService.GetApplication", "service": { - "fullName": "google.ads.admanager.v1.CompanyService", - "shortName": "CompanyService" + "fullName": "google.ads.admanager.v1.ApplicationService", + "shortName": "ApplicationService" }, - "shortName": "ListCompanies" + "shortName": "GetApplication" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.ListCompaniesRequest" + "type": "google.ads.admanager_v1.types.GetApplicationRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, { @@ -934,22 +934,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.services.company_service.pagers.ListCompaniesPager", - "shortName": "list_companies" + "resultType": "google.ads.admanager_v1.types.Application", + "shortName": "get_application" }, - "description": "Sample for ListCompanies", - "file": "admanager_v1_generated_company_service_list_companies_sync.py", + "description": "Sample for GetApplication", + "file": "admanager_v1_generated_application_service_get_application_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_CompanyService_ListCompanies_sync", + "regionTag": "admanager_v1_generated_ApplicationService_GetApplication_sync", "segments": [ { - "end": 52, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 51, "start": 27, "type": "SHORT" }, @@ -969,36 +969,36 @@ "type": "REQUEST_EXECUTION" }, { - "end": 53, + "end": 52, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_company_service_list_companies_sync.py" + "title": "admanager_v1_generated_application_service_get_application_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.CustomFieldServiceClient", - "shortName": "CustomFieldServiceClient" + "fullName": "google.ads.admanager_v1.ApplicationServiceClient", + "shortName": "ApplicationServiceClient" }, - "fullName": "google.ads.admanager_v1.CustomFieldServiceClient.get_custom_field", + "fullName": "google.ads.admanager_v1.ApplicationServiceClient.list_applications", "method": { - "fullName": "google.ads.admanager.v1.CustomFieldService.GetCustomField", + "fullName": "google.ads.admanager.v1.ApplicationService.ListApplications", "service": { - "fullName": "google.ads.admanager.v1.CustomFieldService", - "shortName": "CustomFieldService" + "fullName": "google.ads.admanager.v1.ApplicationService", + "shortName": "ApplicationService" }, - "shortName": "GetCustomField" + "shortName": "ListApplications" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.GetCustomFieldRequest" + "type": "google.ads.admanager_v1.types.ListApplicationsRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -1014,22 +1014,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.CustomField", - "shortName": "get_custom_field" + "resultType": "google.ads.admanager_v1.services.application_service.pagers.ListApplicationsPager", + "shortName": "list_applications" }, - "description": "Sample for GetCustomField", - "file": "admanager_v1_generated_custom_field_service_get_custom_field_sync.py", + "description": "Sample for ListApplications", + "file": "admanager_v1_generated_application_service_list_applications_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_CustomFieldService_GetCustomField_sync", + "regionTag": "admanager_v1_generated_ApplicationService_ListApplications_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -1049,36 +1049,36 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_custom_field_service_get_custom_field_sync.py" + "title": "admanager_v1_generated_application_service_list_applications_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.CustomFieldServiceClient", - "shortName": "CustomFieldServiceClient" + "fullName": "google.ads.admanager_v1.AudienceSegmentServiceClient", + "shortName": "AudienceSegmentServiceClient" }, - "fullName": "google.ads.admanager_v1.CustomFieldServiceClient.list_custom_fields", + "fullName": "google.ads.admanager_v1.AudienceSegmentServiceClient.get_audience_segment", "method": { - "fullName": "google.ads.admanager.v1.CustomFieldService.ListCustomFields", + "fullName": "google.ads.admanager.v1.AudienceSegmentService.GetAudienceSegment", "service": { - "fullName": "google.ads.admanager.v1.CustomFieldService", - "shortName": "CustomFieldService" + "fullName": "google.ads.admanager.v1.AudienceSegmentService", + "shortName": "AudienceSegmentService" }, - "shortName": "ListCustomFields" + "shortName": "GetAudienceSegment" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.ListCustomFieldsRequest" + "type": "google.ads.admanager_v1.types.GetAudienceSegmentRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, { @@ -1094,22 +1094,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.services.custom_field_service.pagers.ListCustomFieldsPager", - "shortName": "list_custom_fields" + "resultType": "google.ads.admanager_v1.types.AudienceSegment", + "shortName": "get_audience_segment" }, - "description": "Sample for ListCustomFields", - "file": "admanager_v1_generated_custom_field_service_list_custom_fields_sync.py", + "description": "Sample for GetAudienceSegment", + "file": "admanager_v1_generated_audience_segment_service_get_audience_segment_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_CustomFieldService_ListCustomFields_sync", + "regionTag": "admanager_v1_generated_AudienceSegmentService_GetAudienceSegment_sync", "segments": [ { - "end": 52, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 51, "start": 27, "type": "SHORT" }, @@ -1129,36 +1129,36 @@ "type": "REQUEST_EXECUTION" }, { - "end": 53, + "end": 52, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_custom_field_service_list_custom_fields_sync.py" + "title": "admanager_v1_generated_audience_segment_service_get_audience_segment_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.CustomTargetingKeyServiceClient", - "shortName": "CustomTargetingKeyServiceClient" + "fullName": "google.ads.admanager_v1.AudienceSegmentServiceClient", + "shortName": "AudienceSegmentServiceClient" }, - "fullName": "google.ads.admanager_v1.CustomTargetingKeyServiceClient.get_custom_targeting_key", + "fullName": "google.ads.admanager_v1.AudienceSegmentServiceClient.list_audience_segments", "method": { - "fullName": "google.ads.admanager.v1.CustomTargetingKeyService.GetCustomTargetingKey", + "fullName": "google.ads.admanager.v1.AudienceSegmentService.ListAudienceSegments", "service": { - "fullName": "google.ads.admanager.v1.CustomTargetingKeyService", - "shortName": "CustomTargetingKeyService" + "fullName": "google.ads.admanager.v1.AudienceSegmentService", + "shortName": "AudienceSegmentService" }, - "shortName": "GetCustomTargetingKey" + "shortName": "ListAudienceSegments" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.GetCustomTargetingKeyRequest" + "type": "google.ads.admanager_v1.types.ListAudienceSegmentsRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -1174,22 +1174,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.CustomTargetingKey", - "shortName": "get_custom_targeting_key" + "resultType": "google.ads.admanager_v1.services.audience_segment_service.pagers.ListAudienceSegmentsPager", + "shortName": "list_audience_segments" }, - "description": "Sample for GetCustomTargetingKey", - "file": "admanager_v1_generated_custom_targeting_key_service_get_custom_targeting_key_sync.py", + "description": "Sample for ListAudienceSegments", + "file": "admanager_v1_generated_audience_segment_service_list_audience_segments_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_CustomTargetingKeyService_GetCustomTargetingKey_sync", + "regionTag": "admanager_v1_generated_AudienceSegmentService_ListAudienceSegments_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -1209,36 +1209,36 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_custom_targeting_key_service_get_custom_targeting_key_sync.py" + "title": "admanager_v1_generated_audience_segment_service_list_audience_segments_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.CustomTargetingKeyServiceClient", - "shortName": "CustomTargetingKeyServiceClient" + "fullName": "google.ads.admanager_v1.BandwidthGroupServiceClient", + "shortName": "BandwidthGroupServiceClient" }, - "fullName": "google.ads.admanager_v1.CustomTargetingKeyServiceClient.list_custom_targeting_keys", + "fullName": "google.ads.admanager_v1.BandwidthGroupServiceClient.get_bandwidth_group", "method": { - "fullName": "google.ads.admanager.v1.CustomTargetingKeyService.ListCustomTargetingKeys", + "fullName": "google.ads.admanager.v1.BandwidthGroupService.GetBandwidthGroup", "service": { - "fullName": "google.ads.admanager.v1.CustomTargetingKeyService", - "shortName": "CustomTargetingKeyService" + "fullName": "google.ads.admanager.v1.BandwidthGroupService", + "shortName": "BandwidthGroupService" }, - "shortName": "ListCustomTargetingKeys" + "shortName": "GetBandwidthGroup" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.ListCustomTargetingKeysRequest" + "type": "google.ads.admanager_v1.types.GetBandwidthGroupRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, { @@ -1254,22 +1254,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.services.custom_targeting_key_service.pagers.ListCustomTargetingKeysPager", - "shortName": "list_custom_targeting_keys" + "resultType": "google.ads.admanager_v1.types.BandwidthGroup", + "shortName": "get_bandwidth_group" }, - "description": "Sample for ListCustomTargetingKeys", - "file": "admanager_v1_generated_custom_targeting_key_service_list_custom_targeting_keys_sync.py", + "description": "Sample for GetBandwidthGroup", + "file": "admanager_v1_generated_bandwidth_group_service_get_bandwidth_group_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_CustomTargetingKeyService_ListCustomTargetingKeys_sync", + "regionTag": "admanager_v1_generated_BandwidthGroupService_GetBandwidthGroup_sync", "segments": [ { - "end": 52, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 51, "start": 27, "type": "SHORT" }, @@ -1289,36 +1289,36 @@ "type": "REQUEST_EXECUTION" }, { - "end": 53, + "end": 52, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_custom_targeting_key_service_list_custom_targeting_keys_sync.py" + "title": "admanager_v1_generated_bandwidth_group_service_get_bandwidth_group_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.CustomTargetingValueServiceClient", - "shortName": "CustomTargetingValueServiceClient" + "fullName": "google.ads.admanager_v1.BandwidthGroupServiceClient", + "shortName": "BandwidthGroupServiceClient" }, - "fullName": "google.ads.admanager_v1.CustomTargetingValueServiceClient.get_custom_targeting_value", + "fullName": "google.ads.admanager_v1.BandwidthGroupServiceClient.list_bandwidth_groups", "method": { - "fullName": "google.ads.admanager.v1.CustomTargetingValueService.GetCustomTargetingValue", + "fullName": "google.ads.admanager.v1.BandwidthGroupService.ListBandwidthGroups", "service": { - "fullName": "google.ads.admanager.v1.CustomTargetingValueService", - "shortName": "CustomTargetingValueService" + "fullName": "google.ads.admanager.v1.BandwidthGroupService", + "shortName": "BandwidthGroupService" }, - "shortName": "GetCustomTargetingValue" + "shortName": "ListBandwidthGroups" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.GetCustomTargetingValueRequest" + "type": "google.ads.admanager_v1.types.ListBandwidthGroupsRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -1334,22 +1334,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.CustomTargetingValue", - "shortName": "get_custom_targeting_value" + "resultType": "google.ads.admanager_v1.services.bandwidth_group_service.pagers.ListBandwidthGroupsPager", + "shortName": "list_bandwidth_groups" }, - "description": "Sample for GetCustomTargetingValue", - "file": "admanager_v1_generated_custom_targeting_value_service_get_custom_targeting_value_sync.py", + "description": "Sample for ListBandwidthGroups", + "file": "admanager_v1_generated_bandwidth_group_service_list_bandwidth_groups_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_CustomTargetingValueService_GetCustomTargetingValue_sync", + "regionTag": "admanager_v1_generated_BandwidthGroupService_ListBandwidthGroups_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -1369,36 +1369,36 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_custom_targeting_value_service_get_custom_targeting_value_sync.py" + "title": "admanager_v1_generated_bandwidth_group_service_list_bandwidth_groups_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.CustomTargetingValueServiceClient", - "shortName": "CustomTargetingValueServiceClient" + "fullName": "google.ads.admanager_v1.BrowserLanguageServiceClient", + "shortName": "BrowserLanguageServiceClient" }, - "fullName": "google.ads.admanager_v1.CustomTargetingValueServiceClient.list_custom_targeting_values", + "fullName": "google.ads.admanager_v1.BrowserLanguageServiceClient.get_browser_language", "method": { - "fullName": "google.ads.admanager.v1.CustomTargetingValueService.ListCustomTargetingValues", + "fullName": "google.ads.admanager.v1.BrowserLanguageService.GetBrowserLanguage", "service": { - "fullName": "google.ads.admanager.v1.CustomTargetingValueService", - "shortName": "CustomTargetingValueService" + "fullName": "google.ads.admanager.v1.BrowserLanguageService", + "shortName": "BrowserLanguageService" }, - "shortName": "ListCustomTargetingValues" + "shortName": "GetBrowserLanguage" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.ListCustomTargetingValuesRequest" + "type": "google.ads.admanager_v1.types.GetBrowserLanguageRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, { @@ -1414,22 +1414,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.services.custom_targeting_value_service.pagers.ListCustomTargetingValuesPager", - "shortName": "list_custom_targeting_values" + "resultType": "google.ads.admanager_v1.types.BrowserLanguage", + "shortName": "get_browser_language" }, - "description": "Sample for ListCustomTargetingValues", - "file": "admanager_v1_generated_custom_targeting_value_service_list_custom_targeting_values_sync.py", + "description": "Sample for GetBrowserLanguage", + "file": "admanager_v1_generated_browser_language_service_get_browser_language_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_CustomTargetingValueService_ListCustomTargetingValues_sync", + "regionTag": "admanager_v1_generated_BrowserLanguageService_GetBrowserLanguage_sync", "segments": [ { - "end": 52, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 51, "start": 27, "type": "SHORT" }, @@ -1449,36 +1449,36 @@ "type": "REQUEST_EXECUTION" }, { - "end": 53, + "end": 52, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_custom_targeting_value_service_list_custom_targeting_values_sync.py" + "title": "admanager_v1_generated_browser_language_service_get_browser_language_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.DeviceCategoryServiceClient", - "shortName": "DeviceCategoryServiceClient" + "fullName": "google.ads.admanager_v1.BrowserLanguageServiceClient", + "shortName": "BrowserLanguageServiceClient" }, - "fullName": "google.ads.admanager_v1.DeviceCategoryServiceClient.get_device_category", + "fullName": "google.ads.admanager_v1.BrowserLanguageServiceClient.list_browser_languages", "method": { - "fullName": "google.ads.admanager.v1.DeviceCategoryService.GetDeviceCategory", + "fullName": "google.ads.admanager.v1.BrowserLanguageService.ListBrowserLanguages", "service": { - "fullName": "google.ads.admanager.v1.DeviceCategoryService", - "shortName": "DeviceCategoryService" + "fullName": "google.ads.admanager.v1.BrowserLanguageService", + "shortName": "BrowserLanguageService" }, - "shortName": "GetDeviceCategory" + "shortName": "ListBrowserLanguages" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.GetDeviceCategoryRequest" + "type": "google.ads.admanager_v1.types.ListBrowserLanguagesRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -1494,22 +1494,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.DeviceCategory", - "shortName": "get_device_category" + "resultType": "google.ads.admanager_v1.services.browser_language_service.pagers.ListBrowserLanguagesPager", + "shortName": "list_browser_languages" }, - "description": "Sample for GetDeviceCategory", - "file": "admanager_v1_generated_device_category_service_get_device_category_sync.py", + "description": "Sample for ListBrowserLanguages", + "file": "admanager_v1_generated_browser_language_service_list_browser_languages_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_DeviceCategoryService_GetDeviceCategory_sync", + "regionTag": "admanager_v1_generated_BrowserLanguageService_ListBrowserLanguages_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -1529,36 +1529,36 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_device_category_service_get_device_category_sync.py" + "title": "admanager_v1_generated_browser_language_service_list_browser_languages_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.DeviceCategoryServiceClient", - "shortName": "DeviceCategoryServiceClient" + "fullName": "google.ads.admanager_v1.BrowserServiceClient", + "shortName": "BrowserServiceClient" }, - "fullName": "google.ads.admanager_v1.DeviceCategoryServiceClient.list_device_categories", + "fullName": "google.ads.admanager_v1.BrowserServiceClient.get_browser", "method": { - "fullName": "google.ads.admanager.v1.DeviceCategoryService.ListDeviceCategories", + "fullName": "google.ads.admanager.v1.BrowserService.GetBrowser", "service": { - "fullName": "google.ads.admanager.v1.DeviceCategoryService", - "shortName": "DeviceCategoryService" + "fullName": "google.ads.admanager.v1.BrowserService", + "shortName": "BrowserService" }, - "shortName": "ListDeviceCategories" + "shortName": "GetBrowser" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.ListDeviceCategoriesRequest" + "type": "google.ads.admanager_v1.types.GetBrowserRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, { @@ -1574,22 +1574,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.services.device_category_service.pagers.ListDeviceCategoriesPager", - "shortName": "list_device_categories" + "resultType": "google.ads.admanager_v1.types.Browser", + "shortName": "get_browser" }, - "description": "Sample for ListDeviceCategories", - "file": "admanager_v1_generated_device_category_service_list_device_categories_sync.py", + "description": "Sample for GetBrowser", + "file": "admanager_v1_generated_browser_service_get_browser_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_DeviceCategoryService_ListDeviceCategories_sync", + "regionTag": "admanager_v1_generated_BrowserService_GetBrowser_sync", "segments": [ { - "end": 52, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 51, "start": 27, "type": "SHORT" }, @@ -1609,42 +1609,38 @@ "type": "REQUEST_EXECUTION" }, { - "end": 53, + "end": 52, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_device_category_service_list_device_categories_sync.py" + "title": "admanager_v1_generated_browser_service_get_browser_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient", - "shortName": "EntitySignalsMappingServiceClient" + "fullName": "google.ads.admanager_v1.BrowserServiceClient", + "shortName": "BrowserServiceClient" }, - "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient.batch_create_entity_signals_mappings", + "fullName": "google.ads.admanager_v1.BrowserServiceClient.list_browsers", "method": { - "fullName": "google.ads.admanager.v1.EntitySignalsMappingService.BatchCreateEntitySignalsMappings", + "fullName": "google.ads.admanager.v1.BrowserService.ListBrowsers", "service": { - "fullName": "google.ads.admanager.v1.EntitySignalsMappingService", - "shortName": "EntitySignalsMappingService" + "fullName": "google.ads.admanager.v1.BrowserService", + "shortName": "BrowserService" }, - "shortName": "BatchCreateEntitySignalsMappings" + "shortName": "ListBrowsers" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.BatchCreateEntitySignalsMappingsRequest" + "type": "google.ads.admanager_v1.types.ListBrowsersRequest" }, { "name": "parent", "type": "str" }, - { - "name": "requests", - "type": "MutableSequence[google.ads.admanager_v1.types.CreateEntitySignalsMappingRequest]" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -1658,22 +1654,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.BatchCreateEntitySignalsMappingsResponse", - "shortName": "batch_create_entity_signals_mappings" + "resultType": "google.ads.admanager_v1.services.browser_service.pagers.ListBrowsersPager", + "shortName": "list_browsers" }, - "description": "Sample for BatchCreateEntitySignalsMappings", - "file": "admanager_v1_generated_entity_signals_mapping_service_batch_create_entity_signals_mappings_sync.py", + "description": "Sample for ListBrowsers", + "file": "admanager_v1_generated_browser_service_list_browsers_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_EntitySignalsMappingService_BatchCreateEntitySignalsMappings_sync", + "regionTag": "admanager_v1_generated_BrowserService_ListBrowsers_sync", "segments": [ { - "end": 56, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 56, + "end": 52, "start": 27, "type": "SHORT" }, @@ -1683,52 +1679,48 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 50, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 53, - "start": 51, + "end": 48, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 57, - "start": 54, + "end": 53, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_entity_signals_mapping_service_batch_create_entity_signals_mappings_sync.py" + "title": "admanager_v1_generated_browser_service_list_browsers_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient", - "shortName": "EntitySignalsMappingServiceClient" + "fullName": "google.ads.admanager_v1.CmsMetadataKeyServiceClient", + "shortName": "CmsMetadataKeyServiceClient" }, - "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient.batch_update_entity_signals_mappings", + "fullName": "google.ads.admanager_v1.CmsMetadataKeyServiceClient.get_cms_metadata_key", "method": { - "fullName": "google.ads.admanager.v1.EntitySignalsMappingService.BatchUpdateEntitySignalsMappings", + "fullName": "google.ads.admanager.v1.CmsMetadataKeyService.GetCmsMetadataKey", "service": { - "fullName": "google.ads.admanager.v1.EntitySignalsMappingService", - "shortName": "EntitySignalsMappingService" + "fullName": "google.ads.admanager.v1.CmsMetadataKeyService", + "shortName": "CmsMetadataKeyService" }, - "shortName": "BatchUpdateEntitySignalsMappings" + "shortName": "GetCmsMetadataKey" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.BatchUpdateEntitySignalsMappingsRequest" + "type": "google.ads.admanager_v1.types.GetCmsMetadataKeyRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, - { - "name": "requests", - "type": "MutableSequence[google.ads.admanager_v1.types.UpdateEntitySignalsMappingRequest]" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -1742,22 +1734,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.BatchUpdateEntitySignalsMappingsResponse", - "shortName": "batch_update_entity_signals_mappings" + "resultType": "google.ads.admanager_v1.types.CmsMetadataKey", + "shortName": "get_cms_metadata_key" }, - "description": "Sample for BatchUpdateEntitySignalsMappings", - "file": "admanager_v1_generated_entity_signals_mapping_service_batch_update_entity_signals_mappings_sync.py", + "description": "Sample for GetCmsMetadataKey", + "file": "admanager_v1_generated_cms_metadata_key_service_get_cms_metadata_key_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_EntitySignalsMappingService_BatchUpdateEntitySignalsMappings_sync", + "regionTag": "admanager_v1_generated_CmsMetadataKeyService_GetCmsMetadataKey_sync", "segments": [ { - "end": 55, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 55, + "end": 51, "start": 27, "type": "SHORT" }, @@ -1767,52 +1759,48 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 49, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 52, - "start": 50, + "end": 48, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 56, - "start": 53, + "end": 52, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_entity_signals_mapping_service_batch_update_entity_signals_mappings_sync.py" + "title": "admanager_v1_generated_cms_metadata_key_service_get_cms_metadata_key_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient", - "shortName": "EntitySignalsMappingServiceClient" + "fullName": "google.ads.admanager_v1.CmsMetadataKeyServiceClient", + "shortName": "CmsMetadataKeyServiceClient" }, - "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient.create_entity_signals_mapping", + "fullName": "google.ads.admanager_v1.CmsMetadataKeyServiceClient.list_cms_metadata_keys", "method": { - "fullName": "google.ads.admanager.v1.EntitySignalsMappingService.CreateEntitySignalsMapping", + "fullName": "google.ads.admanager.v1.CmsMetadataKeyService.ListCmsMetadataKeys", "service": { - "fullName": "google.ads.admanager.v1.EntitySignalsMappingService", - "shortName": "EntitySignalsMappingService" + "fullName": "google.ads.admanager.v1.CmsMetadataKeyService", + "shortName": "CmsMetadataKeyService" }, - "shortName": "CreateEntitySignalsMapping" + "shortName": "ListCmsMetadataKeys" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.CreateEntitySignalsMappingRequest" + "type": "google.ads.admanager_v1.types.ListCmsMetadataKeysRequest" }, { "name": "parent", "type": "str" }, - { - "name": "entity_signals_mapping", - "type": "google.ads.admanager_v1.types.EntitySignalsMapping" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -1826,22 +1814,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.EntitySignalsMapping", - "shortName": "create_entity_signals_mapping" + "resultType": "google.ads.admanager_v1.services.cms_metadata_key_service.pagers.ListCmsMetadataKeysPager", + "shortName": "list_cms_metadata_keys" }, - "description": "Sample for CreateEntitySignalsMapping", - "file": "admanager_v1_generated_entity_signals_mapping_service_create_entity_signals_mapping_sync.py", + "description": "Sample for ListCmsMetadataKeys", + "file": "admanager_v1_generated_cms_metadata_key_service_list_cms_metadata_keys_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_EntitySignalsMappingService_CreateEntitySignalsMapping_sync", + "regionTag": "admanager_v1_generated_CmsMetadataKeyService_ListCmsMetadataKeys_sync", "segments": [ { - "end": 55, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 55, + "end": 52, "start": 27, "type": "SHORT" }, @@ -1851,43 +1839,43 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 49, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 52, - "start": 50, + "end": 48, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 56, - "start": 53, + "end": 53, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_entity_signals_mapping_service_create_entity_signals_mapping_sync.py" + "title": "admanager_v1_generated_cms_metadata_key_service_list_cms_metadata_keys_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient", - "shortName": "EntitySignalsMappingServiceClient" + "fullName": "google.ads.admanager_v1.CmsMetadataValueServiceClient", + "shortName": "CmsMetadataValueServiceClient" }, - "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient.get_entity_signals_mapping", + "fullName": "google.ads.admanager_v1.CmsMetadataValueServiceClient.get_cms_metadata_value", "method": { - "fullName": "google.ads.admanager.v1.EntitySignalsMappingService.GetEntitySignalsMapping", + "fullName": "google.ads.admanager.v1.CmsMetadataValueService.GetCmsMetadataValue", "service": { - "fullName": "google.ads.admanager.v1.EntitySignalsMappingService", - "shortName": "EntitySignalsMappingService" + "fullName": "google.ads.admanager.v1.CmsMetadataValueService", + "shortName": "CmsMetadataValueService" }, - "shortName": "GetEntitySignalsMapping" + "shortName": "GetCmsMetadataValue" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.GetEntitySignalsMappingRequest" + "type": "google.ads.admanager_v1.types.GetCmsMetadataValueRequest" }, { "name": "name", @@ -1906,14 +1894,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.EntitySignalsMapping", - "shortName": "get_entity_signals_mapping" + "resultType": "google.ads.admanager_v1.types.CmsMetadataValue", + "shortName": "get_cms_metadata_value" }, - "description": "Sample for GetEntitySignalsMapping", - "file": "admanager_v1_generated_entity_signals_mapping_service_get_entity_signals_mapping_sync.py", + "description": "Sample for GetCmsMetadataValue", + "file": "admanager_v1_generated_cms_metadata_value_service_get_cms_metadata_value_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_EntitySignalsMappingService_GetEntitySignalsMapping_sync", + "regionTag": "admanager_v1_generated_CmsMetadataValueService_GetCmsMetadataValue_sync", "segments": [ { "end": 51, @@ -1946,28 +1934,28 @@ "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_entity_signals_mapping_service_get_entity_signals_mapping_sync.py" + "title": "admanager_v1_generated_cms_metadata_value_service_get_cms_metadata_value_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient", - "shortName": "EntitySignalsMappingServiceClient" + "fullName": "google.ads.admanager_v1.CmsMetadataValueServiceClient", + "shortName": "CmsMetadataValueServiceClient" }, - "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient.list_entity_signals_mappings", + "fullName": "google.ads.admanager_v1.CmsMetadataValueServiceClient.list_cms_metadata_values", "method": { - "fullName": "google.ads.admanager.v1.EntitySignalsMappingService.ListEntitySignalsMappings", + "fullName": "google.ads.admanager.v1.CmsMetadataValueService.ListCmsMetadataValues", "service": { - "fullName": "google.ads.admanager.v1.EntitySignalsMappingService", - "shortName": "EntitySignalsMappingService" + "fullName": "google.ads.admanager.v1.CmsMetadataValueService", + "shortName": "CmsMetadataValueService" }, - "shortName": "ListEntitySignalsMappings" + "shortName": "ListCmsMetadataValues" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.ListEntitySignalsMappingsRequest" + "type": "google.ads.admanager_v1.types.ListCmsMetadataValuesRequest" }, { "name": "parent", @@ -1986,14 +1974,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.services.entity_signals_mapping_service.pagers.ListEntitySignalsMappingsPager", - "shortName": "list_entity_signals_mappings" + "resultType": "google.ads.admanager_v1.services.cms_metadata_value_service.pagers.ListCmsMetadataValuesPager", + "shortName": "list_cms_metadata_values" }, - "description": "Sample for ListEntitySignalsMappings", - "file": "admanager_v1_generated_entity_signals_mapping_service_list_entity_signals_mappings_sync.py", + "description": "Sample for ListCmsMetadataValues", + "file": "admanager_v1_generated_cms_metadata_value_service_list_cms_metadata_values_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_EntitySignalsMappingService_ListEntitySignalsMappings_sync", + "regionTag": "admanager_v1_generated_CmsMetadataValueService_ListCmsMetadataValues_sync", "segments": [ { "end": 52, @@ -2026,36 +2014,32 @@ "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_entity_signals_mapping_service_list_entity_signals_mappings_sync.py" + "title": "admanager_v1_generated_cms_metadata_value_service_list_cms_metadata_values_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient", - "shortName": "EntitySignalsMappingServiceClient" + "fullName": "google.ads.admanager_v1.CompanyServiceClient", + "shortName": "CompanyServiceClient" }, - "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient.update_entity_signals_mapping", + "fullName": "google.ads.admanager_v1.CompanyServiceClient.get_company", "method": { - "fullName": "google.ads.admanager.v1.EntitySignalsMappingService.UpdateEntitySignalsMapping", + "fullName": "google.ads.admanager.v1.CompanyService.GetCompany", "service": { - "fullName": "google.ads.admanager.v1.EntitySignalsMappingService", - "shortName": "EntitySignalsMappingService" + "fullName": "google.ads.admanager.v1.CompanyService", + "shortName": "CompanyService" }, - "shortName": "UpdateEntitySignalsMapping" + "shortName": "GetCompany" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.UpdateEntitySignalsMappingRequest" - }, - { - "name": "entity_signals_mapping", - "type": "google.ads.admanager_v1.types.EntitySignalsMapping" + "type": "google.ads.admanager_v1.types.GetCompanyRequest" }, { - "name": "update_mask", - "type": "google.protobuf.field_mask_pb2.FieldMask" + "name": "name", + "type": "str" }, { "name": "retry", @@ -2070,22 +2054,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.EntitySignalsMapping", - "shortName": "update_entity_signals_mapping" + "resultType": "google.ads.admanager_v1.types.Company", + "shortName": "get_company" }, - "description": "Sample for UpdateEntitySignalsMapping", - "file": "admanager_v1_generated_entity_signals_mapping_service_update_entity_signals_mapping_sync.py", + "description": "Sample for GetCompany", + "file": "admanager_v1_generated_company_service_get_company_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_EntitySignalsMappingService_UpdateEntitySignalsMapping_sync", + "regionTag": "admanager_v1_generated_CompanyService_GetCompany_sync", "segments": [ { - "end": 54, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 54, + "end": 51, "start": 27, "type": "SHORT" }, @@ -2095,46 +2079,46 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 48, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 51, - "start": 49, + "end": 48, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 55, - "start": 52, + "end": 52, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_entity_signals_mapping_service_update_entity_signals_mapping_sync.py" + "title": "admanager_v1_generated_company_service_get_company_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.GeoTargetServiceClient", - "shortName": "GeoTargetServiceClient" + "fullName": "google.ads.admanager_v1.CompanyServiceClient", + "shortName": "CompanyServiceClient" }, - "fullName": "google.ads.admanager_v1.GeoTargetServiceClient.get_geo_target", + "fullName": "google.ads.admanager_v1.CompanyServiceClient.list_companies", "method": { - "fullName": "google.ads.admanager.v1.GeoTargetService.GetGeoTarget", + "fullName": "google.ads.admanager.v1.CompanyService.ListCompanies", "service": { - "fullName": "google.ads.admanager.v1.GeoTargetService", - "shortName": "GeoTargetService" + "fullName": "google.ads.admanager.v1.CompanyService", + "shortName": "CompanyService" }, - "shortName": "GetGeoTarget" + "shortName": "ListCompanies" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.GetGeoTargetRequest" + "type": "google.ads.admanager_v1.types.ListCompaniesRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -2150,22 +2134,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.GeoTarget", - "shortName": "get_geo_target" + "resultType": "google.ads.admanager_v1.services.company_service.pagers.ListCompaniesPager", + "shortName": "list_companies" }, - "description": "Sample for GetGeoTarget", - "file": "admanager_v1_generated_geo_target_service_get_geo_target_sync.py", + "description": "Sample for ListCompanies", + "file": "admanager_v1_generated_company_service_list_companies_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_GeoTargetService_GetGeoTarget_sync", + "regionTag": "admanager_v1_generated_CompanyService_ListCompanies_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -2185,38 +2169,42 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_geo_target_service_get_geo_target_sync.py" + "title": "admanager_v1_generated_company_service_list_companies_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.GeoTargetServiceClient", - "shortName": "GeoTargetServiceClient" + "fullName": "google.ads.admanager_v1.ContactServiceClient", + "shortName": "ContactServiceClient" }, - "fullName": "google.ads.admanager_v1.GeoTargetServiceClient.list_geo_targets", + "fullName": "google.ads.admanager_v1.ContactServiceClient.batch_create_contacts", "method": { - "fullName": "google.ads.admanager.v1.GeoTargetService.ListGeoTargets", + "fullName": "google.ads.admanager.v1.ContactService.BatchCreateContacts", "service": { - "fullName": "google.ads.admanager.v1.GeoTargetService", - "shortName": "GeoTargetService" + "fullName": "google.ads.admanager.v1.ContactService", + "shortName": "ContactService" }, - "shortName": "ListGeoTargets" + "shortName": "BatchCreateContacts" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.ListGeoTargetsRequest" + "type": "google.ads.admanager_v1.types.BatchCreateContactsRequest" }, { "name": "parent", "type": "str" }, + { + "name": "requests", + "type": "MutableSequence[google.ads.admanager_v1.types.CreateContactRequest]" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -2230,22 +2218,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.services.geo_target_service.pagers.ListGeoTargetsPager", - "shortName": "list_geo_targets" + "resultType": "google.ads.admanager_v1.types.BatchCreateContactsResponse", + "shortName": "batch_create_contacts" }, - "description": "Sample for ListGeoTargets", - "file": "admanager_v1_generated_geo_target_service_list_geo_targets_sync.py", + "description": "Sample for BatchCreateContacts", + "file": "admanager_v1_generated_contact_service_batch_create_contacts_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_GeoTargetService_ListGeoTargets_sync", + "regionTag": "admanager_v1_generated_ContactService_BatchCreateContacts_sync", "segments": [ { - "end": 52, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 55, "start": 27, "type": "SHORT" }, @@ -2255,48 +2243,52 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 49, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 52, + "start": 50, "type": "REQUEST_EXECUTION" }, { - "end": 53, - "start": 49, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_geo_target_service_list_geo_targets_sync.py" + "title": "admanager_v1_generated_contact_service_batch_create_contacts_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.NetworkServiceClient", - "shortName": "NetworkServiceClient" + "fullName": "google.ads.admanager_v1.ContactServiceClient", + "shortName": "ContactServiceClient" }, - "fullName": "google.ads.admanager_v1.NetworkServiceClient.get_network", + "fullName": "google.ads.admanager_v1.ContactServiceClient.batch_update_contacts", "method": { - "fullName": "google.ads.admanager.v1.NetworkService.GetNetwork", + "fullName": "google.ads.admanager.v1.ContactService.BatchUpdateContacts", "service": { - "fullName": "google.ads.admanager.v1.NetworkService", - "shortName": "NetworkService" + "fullName": "google.ads.admanager.v1.ContactService", + "shortName": "ContactService" }, - "shortName": "GetNetwork" + "shortName": "BatchUpdateContacts" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.GetNetworkRequest" + "type": "google.ads.admanager_v1.types.BatchUpdateContactsRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, + { + "name": "requests", + "type": "MutableSequence[google.ads.admanager_v1.types.UpdateContactRequest]" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -2310,14 +2302,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.Network", - "shortName": "get_network" + "resultType": "google.ads.admanager_v1.types.BatchUpdateContactsResponse", + "shortName": "batch_update_contacts" }, - "description": "Sample for GetNetwork", - "file": "admanager_v1_generated_network_service_get_network_sync.py", + "description": "Sample for BatchUpdateContacts", + "file": "admanager_v1_generated_contact_service_batch_update_contacts_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_NetworkService_GetNetwork_sync", + "regionTag": "admanager_v1_generated_ContactService_BatchUpdateContacts_sync", "segments": [ { "end": 51, @@ -2350,28 +2342,36 @@ "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_network_service_get_network_sync.py" + "title": "admanager_v1_generated_contact_service_batch_update_contacts_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.NetworkServiceClient", - "shortName": "NetworkServiceClient" + "fullName": "google.ads.admanager_v1.ContactServiceClient", + "shortName": "ContactServiceClient" }, - "fullName": "google.ads.admanager_v1.NetworkServiceClient.list_networks", + "fullName": "google.ads.admanager_v1.ContactServiceClient.create_contact", "method": { - "fullName": "google.ads.admanager.v1.NetworkService.ListNetworks", + "fullName": "google.ads.admanager.v1.ContactService.CreateContact", "service": { - "fullName": "google.ads.admanager.v1.NetworkService", - "shortName": "NetworkService" + "fullName": "google.ads.admanager.v1.ContactService", + "shortName": "ContactService" }, - "shortName": "ListNetworks" + "shortName": "CreateContact" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.ListNetworksRequest" + "type": "google.ads.admanager_v1.types.CreateContactRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "contact", + "type": "google.ads.admanager_v1.types.Contact" }, { "name": "retry", @@ -2386,22 +2386,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.ListNetworksResponse", - "shortName": "list_networks" + "resultType": "google.ads.admanager_v1.types.Contact", + "shortName": "create_contact" }, - "description": "Sample for ListNetworks", - "file": "admanager_v1_generated_network_service_list_networks_sync.py", + "description": "Sample for CreateContact", + "file": "admanager_v1_generated_contact_service_create_contact_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_NetworkService_ListNetworks_sync", + "regionTag": "admanager_v1_generated_ContactService_CreateContact_sync", "segments": [ { - "end": 50, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 50, + "end": 51, "start": 27, "type": "SHORT" }, @@ -2411,43 +2411,43 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 44, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 47, - "start": 45, + "end": 48, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 51, - "start": 48, + "end": 52, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_network_service_list_networks_sync.py" + "title": "admanager_v1_generated_contact_service_create_contact_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.OperatingSystemServiceClient", - "shortName": "OperatingSystemServiceClient" + "fullName": "google.ads.admanager_v1.ContactServiceClient", + "shortName": "ContactServiceClient" }, - "fullName": "google.ads.admanager_v1.OperatingSystemServiceClient.get_operating_system", + "fullName": "google.ads.admanager_v1.ContactServiceClient.get_contact", "method": { - "fullName": "google.ads.admanager.v1.OperatingSystemService.GetOperatingSystem", + "fullName": "google.ads.admanager.v1.ContactService.GetContact", "service": { - "fullName": "google.ads.admanager.v1.OperatingSystemService", - "shortName": "OperatingSystemService" + "fullName": "google.ads.admanager.v1.ContactService", + "shortName": "ContactService" }, - "shortName": "GetOperatingSystem" + "shortName": "GetContact" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.GetOperatingSystemRequest" + "type": "google.ads.admanager_v1.types.GetContactRequest" }, { "name": "name", @@ -2466,14 +2466,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.OperatingSystem", - "shortName": "get_operating_system" + "resultType": "google.ads.admanager_v1.types.Contact", + "shortName": "get_contact" }, - "description": "Sample for GetOperatingSystem", - "file": "admanager_v1_generated_operating_system_service_get_operating_system_sync.py", + "description": "Sample for GetContact", + "file": "admanager_v1_generated_contact_service_get_contact_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_OperatingSystemService_GetOperatingSystem_sync", + "regionTag": "admanager_v1_generated_ContactService_GetContact_sync", "segments": [ { "end": 51, @@ -2506,28 +2506,28 @@ "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_operating_system_service_get_operating_system_sync.py" + "title": "admanager_v1_generated_contact_service_get_contact_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.OperatingSystemServiceClient", - "shortName": "OperatingSystemServiceClient" + "fullName": "google.ads.admanager_v1.ContactServiceClient", + "shortName": "ContactServiceClient" }, - "fullName": "google.ads.admanager_v1.OperatingSystemServiceClient.list_operating_systems", + "fullName": "google.ads.admanager_v1.ContactServiceClient.list_contacts", "method": { - "fullName": "google.ads.admanager.v1.OperatingSystemService.ListOperatingSystems", + "fullName": "google.ads.admanager.v1.ContactService.ListContacts", "service": { - "fullName": "google.ads.admanager.v1.OperatingSystemService", - "shortName": "OperatingSystemService" + "fullName": "google.ads.admanager.v1.ContactService", + "shortName": "ContactService" }, - "shortName": "ListOperatingSystems" + "shortName": "ListContacts" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.ListOperatingSystemsRequest" + "type": "google.ads.admanager_v1.types.ListContactsRequest" }, { "name": "parent", @@ -2546,14 +2546,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.services.operating_system_service.pagers.ListOperatingSystemsPager", - "shortName": "list_operating_systems" + "resultType": "google.ads.admanager_v1.services.contact_service.pagers.ListContactsPager", + "shortName": "list_contacts" }, - "description": "Sample for ListOperatingSystems", - "file": "admanager_v1_generated_operating_system_service_list_operating_systems_sync.py", + "description": "Sample for ListContacts", + "file": "admanager_v1_generated_contact_service_list_contacts_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_OperatingSystemService_ListOperatingSystems_sync", + "regionTag": "admanager_v1_generated_ContactService_ListContacts_sync", "segments": [ { "end": 52, @@ -2586,32 +2586,36 @@ "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_operating_system_service_list_operating_systems_sync.py" + "title": "admanager_v1_generated_contact_service_list_contacts_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.OperatingSystemVersionServiceClient", - "shortName": "OperatingSystemVersionServiceClient" + "fullName": "google.ads.admanager_v1.ContactServiceClient", + "shortName": "ContactServiceClient" }, - "fullName": "google.ads.admanager_v1.OperatingSystemVersionServiceClient.get_operating_system_version", + "fullName": "google.ads.admanager_v1.ContactServiceClient.update_contact", "method": { - "fullName": "google.ads.admanager.v1.OperatingSystemVersionService.GetOperatingSystemVersion", + "fullName": "google.ads.admanager.v1.ContactService.UpdateContact", "service": { - "fullName": "google.ads.admanager.v1.OperatingSystemVersionService", - "shortName": "OperatingSystemVersionService" + "fullName": "google.ads.admanager.v1.ContactService", + "shortName": "ContactService" }, - "shortName": "GetOperatingSystemVersion" + "shortName": "UpdateContact" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.GetOperatingSystemVersionRequest" + "type": "google.ads.admanager_v1.types.UpdateContactRequest" }, { - "name": "name", - "type": "str" + "name": "contact", + "type": "google.ads.admanager_v1.types.Contact" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" }, { "name": "retry", @@ -2626,22 +2630,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.OperatingSystemVersion", - "shortName": "get_operating_system_version" + "resultType": "google.ads.admanager_v1.types.Contact", + "shortName": "update_contact" }, - "description": "Sample for GetOperatingSystemVersion", - "file": "admanager_v1_generated_operating_system_version_service_get_operating_system_version_sync.py", + "description": "Sample for UpdateContact", + "file": "admanager_v1_generated_contact_service_update_contact_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_OperatingSystemVersionService_GetOperatingSystemVersion_sync", + "regionTag": "admanager_v1_generated_ContactService_UpdateContact_sync", "segments": [ { - "end": 51, + "end": 50, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 50, "start": 27, "type": "SHORT" }, @@ -2651,46 +2655,46 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 44, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 47, + "start": 45, "type": "REQUEST_EXECUTION" }, { - "end": 52, - "start": 49, + "end": 51, + "start": 48, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_operating_system_version_service_get_operating_system_version_sync.py" + "title": "admanager_v1_generated_contact_service_update_contact_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.OperatingSystemVersionServiceClient", - "shortName": "OperatingSystemVersionServiceClient" + "fullName": "google.ads.admanager_v1.ContentBundleServiceClient", + "shortName": "ContentBundleServiceClient" }, - "fullName": "google.ads.admanager_v1.OperatingSystemVersionServiceClient.list_operating_system_versions", + "fullName": "google.ads.admanager_v1.ContentBundleServiceClient.get_content_bundle", "method": { - "fullName": "google.ads.admanager.v1.OperatingSystemVersionService.ListOperatingSystemVersions", + "fullName": "google.ads.admanager.v1.ContentBundleService.GetContentBundle", "service": { - "fullName": "google.ads.admanager.v1.OperatingSystemVersionService", - "shortName": "OperatingSystemVersionService" + "fullName": "google.ads.admanager.v1.ContentBundleService", + "shortName": "ContentBundleService" }, - "shortName": "ListOperatingSystemVersions" + "shortName": "GetContentBundle" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.ListOperatingSystemVersionsRequest" + "type": "google.ads.admanager_v1.types.GetContentBundleRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, { @@ -2706,22 +2710,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.services.operating_system_version_service.pagers.ListOperatingSystemVersionsPager", - "shortName": "list_operating_system_versions" + "resultType": "google.ads.admanager_v1.types.ContentBundle", + "shortName": "get_content_bundle" }, - "description": "Sample for ListOperatingSystemVersions", - "file": "admanager_v1_generated_operating_system_version_service_list_operating_system_versions_sync.py", + "description": "Sample for GetContentBundle", + "file": "admanager_v1_generated_content_bundle_service_get_content_bundle_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_OperatingSystemVersionService_ListOperatingSystemVersions_sync", + "regionTag": "admanager_v1_generated_ContentBundleService_GetContentBundle_sync", "segments": [ { - "end": 52, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 51, "start": 27, "type": "SHORT" }, @@ -2741,36 +2745,36 @@ "type": "REQUEST_EXECUTION" }, { - "end": 53, + "end": 52, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_operating_system_version_service_list_operating_system_versions_sync.py" + "title": "admanager_v1_generated_content_bundle_service_get_content_bundle_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.OrderServiceClient", - "shortName": "OrderServiceClient" + "fullName": "google.ads.admanager_v1.ContentBundleServiceClient", + "shortName": "ContentBundleServiceClient" }, - "fullName": "google.ads.admanager_v1.OrderServiceClient.get_order", + "fullName": "google.ads.admanager_v1.ContentBundleServiceClient.list_content_bundles", "method": { - "fullName": "google.ads.admanager.v1.OrderService.GetOrder", + "fullName": "google.ads.admanager.v1.ContentBundleService.ListContentBundles", "service": { - "fullName": "google.ads.admanager.v1.OrderService", - "shortName": "OrderService" + "fullName": "google.ads.admanager.v1.ContentBundleService", + "shortName": "ContentBundleService" }, - "shortName": "GetOrder" + "shortName": "ListContentBundles" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.GetOrderRequest" + "type": "google.ads.admanager_v1.types.ListContentBundlesRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -2786,22 +2790,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.Order", - "shortName": "get_order" + "resultType": "google.ads.admanager_v1.services.content_bundle_service.pagers.ListContentBundlesPager", + "shortName": "list_content_bundles" }, - "description": "Sample for GetOrder", - "file": "admanager_v1_generated_order_service_get_order_sync.py", + "description": "Sample for ListContentBundles", + "file": "admanager_v1_generated_content_bundle_service_list_content_bundles_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_OrderService_GetOrder_sync", + "regionTag": "admanager_v1_generated_ContentBundleService_ListContentBundles_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -2821,36 +2825,36 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_order_service_get_order_sync.py" + "title": "admanager_v1_generated_content_bundle_service_list_content_bundles_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.OrderServiceClient", - "shortName": "OrderServiceClient" + "fullName": "google.ads.admanager_v1.ContentLabelServiceClient", + "shortName": "ContentLabelServiceClient" }, - "fullName": "google.ads.admanager_v1.OrderServiceClient.list_orders", + "fullName": "google.ads.admanager_v1.ContentLabelServiceClient.get_content_label", "method": { - "fullName": "google.ads.admanager.v1.OrderService.ListOrders", + "fullName": "google.ads.admanager.v1.ContentLabelService.GetContentLabel", "service": { - "fullName": "google.ads.admanager.v1.OrderService", - "shortName": "OrderService" + "fullName": "google.ads.admanager.v1.ContentLabelService", + "shortName": "ContentLabelService" }, - "shortName": "ListOrders" + "shortName": "GetContentLabel" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.ListOrdersRequest" + "type": "google.ads.admanager_v1.types.GetContentLabelRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, { @@ -2866,22 +2870,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.services.order_service.pagers.ListOrdersPager", - "shortName": "list_orders" + "resultType": "google.ads.admanager_v1.types.ContentLabel", + "shortName": "get_content_label" }, - "description": "Sample for ListOrders", - "file": "admanager_v1_generated_order_service_list_orders_sync.py", + "description": "Sample for GetContentLabel", + "file": "admanager_v1_generated_content_label_service_get_content_label_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_OrderService_ListOrders_sync", + "regionTag": "admanager_v1_generated_ContentLabelService_GetContentLabel_sync", "segments": [ { - "end": 52, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 51, "start": 27, "type": "SHORT" }, @@ -2901,36 +2905,36 @@ "type": "REQUEST_EXECUTION" }, { - "end": 53, + "end": 52, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_order_service_list_orders_sync.py" + "title": "admanager_v1_generated_content_label_service_get_content_label_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.PlacementServiceClient", - "shortName": "PlacementServiceClient" + "fullName": "google.ads.admanager_v1.ContentLabelServiceClient", + "shortName": "ContentLabelServiceClient" }, - "fullName": "google.ads.admanager_v1.PlacementServiceClient.get_placement", + "fullName": "google.ads.admanager_v1.ContentLabelServiceClient.list_content_labels", "method": { - "fullName": "google.ads.admanager.v1.PlacementService.GetPlacement", + "fullName": "google.ads.admanager.v1.ContentLabelService.ListContentLabels", "service": { - "fullName": "google.ads.admanager.v1.PlacementService", - "shortName": "PlacementService" + "fullName": "google.ads.admanager.v1.ContentLabelService", + "shortName": "ContentLabelService" }, - "shortName": "GetPlacement" + "shortName": "ListContentLabels" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.GetPlacementRequest" + "type": "google.ads.admanager_v1.types.ListContentLabelsRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -2946,22 +2950,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.Placement", - "shortName": "get_placement" + "resultType": "google.ads.admanager_v1.services.content_label_service.pagers.ListContentLabelsPager", + "shortName": "list_content_labels" }, - "description": "Sample for GetPlacement", - "file": "admanager_v1_generated_placement_service_get_placement_sync.py", + "description": "Sample for ListContentLabels", + "file": "admanager_v1_generated_content_label_service_list_content_labels_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_PlacementService_GetPlacement_sync", + "regionTag": "admanager_v1_generated_ContentLabelService_ListContentLabels_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -2981,36 +2985,36 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_placement_service_get_placement_sync.py" + "title": "admanager_v1_generated_content_label_service_list_content_labels_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.PlacementServiceClient", - "shortName": "PlacementServiceClient" + "fullName": "google.ads.admanager_v1.ContentServiceClient", + "shortName": "ContentServiceClient" }, - "fullName": "google.ads.admanager_v1.PlacementServiceClient.list_placements", + "fullName": "google.ads.admanager_v1.ContentServiceClient.get_content", "method": { - "fullName": "google.ads.admanager.v1.PlacementService.ListPlacements", + "fullName": "google.ads.admanager.v1.ContentService.GetContent", "service": { - "fullName": "google.ads.admanager.v1.PlacementService", - "shortName": "PlacementService" + "fullName": "google.ads.admanager.v1.ContentService", + "shortName": "ContentService" }, - "shortName": "ListPlacements" + "shortName": "GetContent" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.ListPlacementsRequest" + "type": "google.ads.admanager_v1.types.GetContentRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, { @@ -3026,22 +3030,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.services.placement_service.pagers.ListPlacementsPager", - "shortName": "list_placements" + "resultType": "google.ads.admanager_v1.types.Content", + "shortName": "get_content" }, - "description": "Sample for ListPlacements", - "file": "admanager_v1_generated_placement_service_list_placements_sync.py", + "description": "Sample for GetContent", + "file": "admanager_v1_generated_content_service_get_content_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_PlacementService_ListPlacements_sync", + "regionTag": "admanager_v1_generated_ContentService_GetContent_sync", "segments": [ { - "end": 52, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 51, "start": 27, "type": "SHORT" }, @@ -3061,42 +3065,38 @@ "type": "REQUEST_EXECUTION" }, { - "end": 53, + "end": 52, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_placement_service_list_placements_sync.py" + "title": "admanager_v1_generated_content_service_get_content_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.PrivateAuctionDealServiceClient", - "shortName": "PrivateAuctionDealServiceClient" + "fullName": "google.ads.admanager_v1.ContentServiceClient", + "shortName": "ContentServiceClient" }, - "fullName": "google.ads.admanager_v1.PrivateAuctionDealServiceClient.create_private_auction_deal", + "fullName": "google.ads.admanager_v1.ContentServiceClient.list_content", "method": { - "fullName": "google.ads.admanager.v1.PrivateAuctionDealService.CreatePrivateAuctionDeal", + "fullName": "google.ads.admanager.v1.ContentService.ListContent", "service": { - "fullName": "google.ads.admanager.v1.PrivateAuctionDealService", - "shortName": "PrivateAuctionDealService" + "fullName": "google.ads.admanager.v1.ContentService", + "shortName": "ContentService" }, - "shortName": "CreatePrivateAuctionDeal" + "shortName": "ListContent" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.CreatePrivateAuctionDealRequest" + "type": "google.ads.admanager_v1.types.ListContentRequest" }, { "name": "parent", "type": "str" }, - { - "name": "private_auction_deal", - "type": "google.ads.admanager_v1.types.PrivateAuctionDeal" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -3110,22 +3110,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.PrivateAuctionDeal", - "shortName": "create_private_auction_deal" + "resultType": "google.ads.admanager_v1.services.content_service.pagers.ListContentPager", + "shortName": "list_content" }, - "description": "Sample for CreatePrivateAuctionDeal", - "file": "admanager_v1_generated_private_auction_deal_service_create_private_auction_deal_sync.py", + "description": "Sample for ListContent", + "file": "admanager_v1_generated_content_service_list_content_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_PrivateAuctionDealService_CreatePrivateAuctionDeal_sync", + "regionTag": "admanager_v1_generated_ContentService_ListContent_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -3145,33 +3145,33 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_private_auction_deal_service_create_private_auction_deal_sync.py" + "title": "admanager_v1_generated_content_service_list_content_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.PrivateAuctionDealServiceClient", - "shortName": "PrivateAuctionDealServiceClient" + "fullName": "google.ads.admanager_v1.CreativeTemplateServiceClient", + "shortName": "CreativeTemplateServiceClient" }, - "fullName": "google.ads.admanager_v1.PrivateAuctionDealServiceClient.get_private_auction_deal", + "fullName": "google.ads.admanager_v1.CreativeTemplateServiceClient.get_creative_template", "method": { - "fullName": "google.ads.admanager.v1.PrivateAuctionDealService.GetPrivateAuctionDeal", + "fullName": "google.ads.admanager.v1.CreativeTemplateService.GetCreativeTemplate", "service": { - "fullName": "google.ads.admanager.v1.PrivateAuctionDealService", - "shortName": "PrivateAuctionDealService" + "fullName": "google.ads.admanager.v1.CreativeTemplateService", + "shortName": "CreativeTemplateService" }, - "shortName": "GetPrivateAuctionDeal" + "shortName": "GetCreativeTemplate" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.GetPrivateAuctionDealRequest" + "type": "google.ads.admanager_v1.types.GetCreativeTemplateRequest" }, { "name": "name", @@ -3190,14 +3190,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.PrivateAuctionDeal", - "shortName": "get_private_auction_deal" + "resultType": "google.ads.admanager_v1.types.CreativeTemplate", + "shortName": "get_creative_template" }, - "description": "Sample for GetPrivateAuctionDeal", - "file": "admanager_v1_generated_private_auction_deal_service_get_private_auction_deal_sync.py", + "description": "Sample for GetCreativeTemplate", + "file": "admanager_v1_generated_creative_template_service_get_creative_template_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_PrivateAuctionDealService_GetPrivateAuctionDeal_sync", + "regionTag": "admanager_v1_generated_CreativeTemplateService_GetCreativeTemplate_sync", "segments": [ { "end": 51, @@ -3230,28 +3230,28 @@ "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_private_auction_deal_service_get_private_auction_deal_sync.py" + "title": "admanager_v1_generated_creative_template_service_get_creative_template_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.PrivateAuctionDealServiceClient", - "shortName": "PrivateAuctionDealServiceClient" + "fullName": "google.ads.admanager_v1.CreativeTemplateServiceClient", + "shortName": "CreativeTemplateServiceClient" }, - "fullName": "google.ads.admanager_v1.PrivateAuctionDealServiceClient.list_private_auction_deals", + "fullName": "google.ads.admanager_v1.CreativeTemplateServiceClient.list_creative_templates", "method": { - "fullName": "google.ads.admanager.v1.PrivateAuctionDealService.ListPrivateAuctionDeals", + "fullName": "google.ads.admanager.v1.CreativeTemplateService.ListCreativeTemplates", "service": { - "fullName": "google.ads.admanager.v1.PrivateAuctionDealService", - "shortName": "PrivateAuctionDealService" + "fullName": "google.ads.admanager.v1.CreativeTemplateService", + "shortName": "CreativeTemplateService" }, - "shortName": "ListPrivateAuctionDeals" + "shortName": "ListCreativeTemplates" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.ListPrivateAuctionDealsRequest" + "type": "google.ads.admanager_v1.types.ListCreativeTemplatesRequest" }, { "name": "parent", @@ -3270,14 +3270,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.services.private_auction_deal_service.pagers.ListPrivateAuctionDealsPager", - "shortName": "list_private_auction_deals" + "resultType": "google.ads.admanager_v1.services.creative_template_service.pagers.ListCreativeTemplatesPager", + "shortName": "list_creative_templates" }, - "description": "Sample for ListPrivateAuctionDeals", - "file": "admanager_v1_generated_private_auction_deal_service_list_private_auction_deals_sync.py", + "description": "Sample for ListCreativeTemplates", + "file": "admanager_v1_generated_creative_template_service_list_creative_templates_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_PrivateAuctionDealService_ListPrivateAuctionDeals_sync", + "regionTag": "admanager_v1_generated_CreativeTemplateService_ListCreativeTemplates_sync", "segments": [ { "end": 52, @@ -3310,36 +3310,36 @@ "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_private_auction_deal_service_list_private_auction_deals_sync.py" + "title": "admanager_v1_generated_creative_template_service_list_creative_templates_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.PrivateAuctionDealServiceClient", - "shortName": "PrivateAuctionDealServiceClient" + "fullName": "google.ads.admanager_v1.CustomFieldServiceClient", + "shortName": "CustomFieldServiceClient" }, - "fullName": "google.ads.admanager_v1.PrivateAuctionDealServiceClient.update_private_auction_deal", + "fullName": "google.ads.admanager_v1.CustomFieldServiceClient.batch_activate_custom_fields", "method": { - "fullName": "google.ads.admanager.v1.PrivateAuctionDealService.UpdatePrivateAuctionDeal", + "fullName": "google.ads.admanager.v1.CustomFieldService.BatchActivateCustomFields", "service": { - "fullName": "google.ads.admanager.v1.PrivateAuctionDealService", - "shortName": "PrivateAuctionDealService" + "fullName": "google.ads.admanager.v1.CustomFieldService", + "shortName": "CustomFieldService" }, - "shortName": "UpdatePrivateAuctionDeal" + "shortName": "BatchActivateCustomFields" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.UpdatePrivateAuctionDealRequest" + "type": "google.ads.admanager_v1.types.BatchActivateCustomFieldsRequest" }, { - "name": "private_auction_deal", - "type": "google.ads.admanager_v1.types.PrivateAuctionDeal" + "name": "parent", + "type": "str" }, { - "name": "update_mask", - "type": "google.protobuf.field_mask_pb2.FieldMask" + "name": "names", + "type": "MutableSequence[str]" }, { "name": "retry", @@ -3354,22 +3354,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.PrivateAuctionDeal", - "shortName": "update_private_auction_deal" + "resultType": "google.ads.admanager_v1.types.BatchActivateCustomFieldsResponse", + "shortName": "batch_activate_custom_fields" }, - "description": "Sample for UpdatePrivateAuctionDeal", - "file": "admanager_v1_generated_private_auction_deal_service_update_private_auction_deal_sync.py", + "description": "Sample for BatchActivateCustomFields", + "file": "admanager_v1_generated_custom_field_service_batch_activate_custom_fields_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_PrivateAuctionDealService_UpdatePrivateAuctionDeal_sync", + "regionTag": "admanager_v1_generated_CustomFieldService_BatchActivateCustomFields_sync", "segments": [ { - "end": 50, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 50, + "end": 52, "start": 27, "type": "SHORT" }, @@ -3379,51 +3379,51 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 44, + "end": 46, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 47, - "start": 45, + "end": 49, + "start": 47, "type": "REQUEST_EXECUTION" }, { - "end": 51, - "start": 48, + "end": 53, + "start": 50, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_private_auction_deal_service_update_private_auction_deal_sync.py" + "title": "admanager_v1_generated_custom_field_service_batch_activate_custom_fields_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.PrivateAuctionServiceClient", - "shortName": "PrivateAuctionServiceClient" + "fullName": "google.ads.admanager_v1.CustomFieldServiceClient", + "shortName": "CustomFieldServiceClient" }, - "fullName": "google.ads.admanager_v1.PrivateAuctionServiceClient.create_private_auction", + "fullName": "google.ads.admanager_v1.CustomFieldServiceClient.batch_create_custom_fields", "method": { - "fullName": "google.ads.admanager.v1.PrivateAuctionService.CreatePrivateAuction", + "fullName": "google.ads.admanager.v1.CustomFieldService.BatchCreateCustomFields", "service": { - "fullName": "google.ads.admanager.v1.PrivateAuctionService", - "shortName": "PrivateAuctionService" + "fullName": "google.ads.admanager.v1.CustomFieldService", + "shortName": "CustomFieldService" }, - "shortName": "CreatePrivateAuction" + "shortName": "BatchCreateCustomFields" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.CreatePrivateAuctionRequest" + "type": "google.ads.admanager_v1.types.BatchCreateCustomFieldsRequest" }, { "name": "parent", "type": "str" }, { - "name": "private_auction", - "type": "google.ads.admanager_v1.types.PrivateAuction" + "name": "requests", + "type": "MutableSequence[google.ads.admanager_v1.types.CreateCustomFieldRequest]" }, { "name": "retry", @@ -3438,22 +3438,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.PrivateAuction", - "shortName": "create_private_auction" + "resultType": "google.ads.admanager_v1.types.BatchCreateCustomFieldsResponse", + "shortName": "batch_create_custom_fields" }, - "description": "Sample for CreatePrivateAuction", - "file": "admanager_v1_generated_private_auction_service_create_private_auction_sync.py", + "description": "Sample for BatchCreateCustomFields", + "file": "admanager_v1_generated_custom_field_service_batch_create_custom_fields_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_PrivateAuctionService_CreatePrivateAuction_sync", + "regionTag": "admanager_v1_generated_CustomFieldService_BatchCreateCustomFields_sync", "segments": [ { - "end": 51, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 55, "start": 27, "type": "SHORT" }, @@ -3463,48 +3463,52 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 49, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 52, + "start": 50, "type": "REQUEST_EXECUTION" }, { - "end": 52, - "start": 49, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_private_auction_service_create_private_auction_sync.py" + "title": "admanager_v1_generated_custom_field_service_batch_create_custom_fields_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.PrivateAuctionServiceClient", - "shortName": "PrivateAuctionServiceClient" + "fullName": "google.ads.admanager_v1.CustomFieldServiceClient", + "shortName": "CustomFieldServiceClient" }, - "fullName": "google.ads.admanager_v1.PrivateAuctionServiceClient.get_private_auction", + "fullName": "google.ads.admanager_v1.CustomFieldServiceClient.batch_deactivate_custom_fields", "method": { - "fullName": "google.ads.admanager.v1.PrivateAuctionService.GetPrivateAuction", + "fullName": "google.ads.admanager.v1.CustomFieldService.BatchDeactivateCustomFields", "service": { - "fullName": "google.ads.admanager.v1.PrivateAuctionService", - "shortName": "PrivateAuctionService" + "fullName": "google.ads.admanager.v1.CustomFieldService", + "shortName": "CustomFieldService" }, - "shortName": "GetPrivateAuction" + "shortName": "BatchDeactivateCustomFields" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.GetPrivateAuctionRequest" + "type": "google.ads.admanager_v1.types.BatchDeactivateCustomFieldsRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, + { + "name": "names", + "type": "MutableSequence[str]" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -3518,22 +3522,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.PrivateAuction", - "shortName": "get_private_auction" + "resultType": "google.ads.admanager_v1.types.BatchDeactivateCustomFieldsResponse", + "shortName": "batch_deactivate_custom_fields" }, - "description": "Sample for GetPrivateAuction", - "file": "admanager_v1_generated_private_auction_service_get_private_auction_sync.py", + "description": "Sample for BatchDeactivateCustomFields", + "file": "admanager_v1_generated_custom_field_service_batch_deactivate_custom_fields_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_PrivateAuctionService_GetPrivateAuction_sync", + "regionTag": "admanager_v1_generated_CustomFieldService_BatchDeactivateCustomFields_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -3543,18 +3547,4242 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 46, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 49, + "start": 47, "type": "REQUEST_EXECUTION" }, { - "end": 52, - "start": 49, + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_custom_field_service_batch_deactivate_custom_fields_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.CustomFieldServiceClient", + "shortName": "CustomFieldServiceClient" + }, + "fullName": "google.ads.admanager_v1.CustomFieldServiceClient.batch_update_custom_fields", + "method": { + "fullName": "google.ads.admanager.v1.CustomFieldService.BatchUpdateCustomFields", + "service": { + "fullName": "google.ads.admanager.v1.CustomFieldService", + "shortName": "CustomFieldService" + }, + "shortName": "BatchUpdateCustomFields" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.BatchUpdateCustomFieldsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "requests", + "type": "MutableSequence[google.ads.admanager_v1.types.UpdateCustomFieldRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.BatchUpdateCustomFieldsResponse", + "shortName": "batch_update_custom_fields" + }, + "description": "Sample for BatchUpdateCustomFields", + "file": "admanager_v1_generated_custom_field_service_batch_update_custom_fields_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_CustomFieldService_BatchUpdateCustomFields_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_custom_field_service_batch_update_custom_fields_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.CustomFieldServiceClient", + "shortName": "CustomFieldServiceClient" + }, + "fullName": "google.ads.admanager_v1.CustomFieldServiceClient.create_custom_field", + "method": { + "fullName": "google.ads.admanager.v1.CustomFieldService.CreateCustomField", + "service": { + "fullName": "google.ads.admanager.v1.CustomFieldService", + "shortName": "CustomFieldService" + }, + "shortName": "CreateCustomField" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.CreateCustomFieldRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "custom_field", + "type": "google.ads.admanager_v1.types.CustomField" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.CustomField", + "shortName": "create_custom_field" + }, + "description": "Sample for CreateCustomField", + "file": "admanager_v1_generated_custom_field_service_create_custom_field_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_CustomFieldService_CreateCustomField_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_custom_field_service_create_custom_field_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.CustomFieldServiceClient", + "shortName": "CustomFieldServiceClient" + }, + "fullName": "google.ads.admanager_v1.CustomFieldServiceClient.get_custom_field", + "method": { + "fullName": "google.ads.admanager.v1.CustomFieldService.GetCustomField", + "service": { + "fullName": "google.ads.admanager.v1.CustomFieldService", + "shortName": "CustomFieldService" + }, + "shortName": "GetCustomField" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.GetCustomFieldRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.CustomField", + "shortName": "get_custom_field" + }, + "description": "Sample for GetCustomField", + "file": "admanager_v1_generated_custom_field_service_get_custom_field_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_CustomFieldService_GetCustomField_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_custom_field_service_get_custom_field_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.CustomFieldServiceClient", + "shortName": "CustomFieldServiceClient" + }, + "fullName": "google.ads.admanager_v1.CustomFieldServiceClient.list_custom_fields", + "method": { + "fullName": "google.ads.admanager.v1.CustomFieldService.ListCustomFields", + "service": { + "fullName": "google.ads.admanager.v1.CustomFieldService", + "shortName": "CustomFieldService" + }, + "shortName": "ListCustomFields" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.ListCustomFieldsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.services.custom_field_service.pagers.ListCustomFieldsPager", + "shortName": "list_custom_fields" + }, + "description": "Sample for ListCustomFields", + "file": "admanager_v1_generated_custom_field_service_list_custom_fields_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_CustomFieldService_ListCustomFields_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_custom_field_service_list_custom_fields_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.CustomFieldServiceClient", + "shortName": "CustomFieldServiceClient" + }, + "fullName": "google.ads.admanager_v1.CustomFieldServiceClient.update_custom_field", + "method": { + "fullName": "google.ads.admanager.v1.CustomFieldService.UpdateCustomField", + "service": { + "fullName": "google.ads.admanager.v1.CustomFieldService", + "shortName": "CustomFieldService" + }, + "shortName": "UpdateCustomField" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.UpdateCustomFieldRequest" + }, + { + "name": "custom_field", + "type": "google.ads.admanager_v1.types.CustomField" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.CustomField", + "shortName": "update_custom_field" + }, + "description": "Sample for UpdateCustomField", + "file": "admanager_v1_generated_custom_field_service_update_custom_field_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_CustomFieldService_UpdateCustomField_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_custom_field_service_update_custom_field_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.CustomTargetingKeyServiceClient", + "shortName": "CustomTargetingKeyServiceClient" + }, + "fullName": "google.ads.admanager_v1.CustomTargetingKeyServiceClient.get_custom_targeting_key", + "method": { + "fullName": "google.ads.admanager.v1.CustomTargetingKeyService.GetCustomTargetingKey", + "service": { + "fullName": "google.ads.admanager.v1.CustomTargetingKeyService", + "shortName": "CustomTargetingKeyService" + }, + "shortName": "GetCustomTargetingKey" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.GetCustomTargetingKeyRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.CustomTargetingKey", + "shortName": "get_custom_targeting_key" + }, + "description": "Sample for GetCustomTargetingKey", + "file": "admanager_v1_generated_custom_targeting_key_service_get_custom_targeting_key_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_CustomTargetingKeyService_GetCustomTargetingKey_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_custom_targeting_key_service_get_custom_targeting_key_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.CustomTargetingKeyServiceClient", + "shortName": "CustomTargetingKeyServiceClient" + }, + "fullName": "google.ads.admanager_v1.CustomTargetingKeyServiceClient.list_custom_targeting_keys", + "method": { + "fullName": "google.ads.admanager.v1.CustomTargetingKeyService.ListCustomTargetingKeys", + "service": { + "fullName": "google.ads.admanager.v1.CustomTargetingKeyService", + "shortName": "CustomTargetingKeyService" + }, + "shortName": "ListCustomTargetingKeys" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.ListCustomTargetingKeysRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.services.custom_targeting_key_service.pagers.ListCustomTargetingKeysPager", + "shortName": "list_custom_targeting_keys" + }, + "description": "Sample for ListCustomTargetingKeys", + "file": "admanager_v1_generated_custom_targeting_key_service_list_custom_targeting_keys_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_CustomTargetingKeyService_ListCustomTargetingKeys_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_custom_targeting_key_service_list_custom_targeting_keys_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.CustomTargetingValueServiceClient", + "shortName": "CustomTargetingValueServiceClient" + }, + "fullName": "google.ads.admanager_v1.CustomTargetingValueServiceClient.get_custom_targeting_value", + "method": { + "fullName": "google.ads.admanager.v1.CustomTargetingValueService.GetCustomTargetingValue", + "service": { + "fullName": "google.ads.admanager.v1.CustomTargetingValueService", + "shortName": "CustomTargetingValueService" + }, + "shortName": "GetCustomTargetingValue" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.GetCustomTargetingValueRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.CustomTargetingValue", + "shortName": "get_custom_targeting_value" + }, + "description": "Sample for GetCustomTargetingValue", + "file": "admanager_v1_generated_custom_targeting_value_service_get_custom_targeting_value_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_CustomTargetingValueService_GetCustomTargetingValue_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_custom_targeting_value_service_get_custom_targeting_value_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.CustomTargetingValueServiceClient", + "shortName": "CustomTargetingValueServiceClient" + }, + "fullName": "google.ads.admanager_v1.CustomTargetingValueServiceClient.list_custom_targeting_values", + "method": { + "fullName": "google.ads.admanager.v1.CustomTargetingValueService.ListCustomTargetingValues", + "service": { + "fullName": "google.ads.admanager.v1.CustomTargetingValueService", + "shortName": "CustomTargetingValueService" + }, + "shortName": "ListCustomTargetingValues" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.ListCustomTargetingValuesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.services.custom_targeting_value_service.pagers.ListCustomTargetingValuesPager", + "shortName": "list_custom_targeting_values" + }, + "description": "Sample for ListCustomTargetingValues", + "file": "admanager_v1_generated_custom_targeting_value_service_list_custom_targeting_values_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_CustomTargetingValueService_ListCustomTargetingValues_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_custom_targeting_value_service_list_custom_targeting_values_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.DeviceCapabilityServiceClient", + "shortName": "DeviceCapabilityServiceClient" + }, + "fullName": "google.ads.admanager_v1.DeviceCapabilityServiceClient.get_device_capability", + "method": { + "fullName": "google.ads.admanager.v1.DeviceCapabilityService.GetDeviceCapability", + "service": { + "fullName": "google.ads.admanager.v1.DeviceCapabilityService", + "shortName": "DeviceCapabilityService" + }, + "shortName": "GetDeviceCapability" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.GetDeviceCapabilityRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.DeviceCapability", + "shortName": "get_device_capability" + }, + "description": "Sample for GetDeviceCapability", + "file": "admanager_v1_generated_device_capability_service_get_device_capability_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_DeviceCapabilityService_GetDeviceCapability_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_device_capability_service_get_device_capability_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.DeviceCapabilityServiceClient", + "shortName": "DeviceCapabilityServiceClient" + }, + "fullName": "google.ads.admanager_v1.DeviceCapabilityServiceClient.list_device_capabilities", + "method": { + "fullName": "google.ads.admanager.v1.DeviceCapabilityService.ListDeviceCapabilities", + "service": { + "fullName": "google.ads.admanager.v1.DeviceCapabilityService", + "shortName": "DeviceCapabilityService" + }, + "shortName": "ListDeviceCapabilities" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.ListDeviceCapabilitiesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.services.device_capability_service.pagers.ListDeviceCapabilitiesPager", + "shortName": "list_device_capabilities" + }, + "description": "Sample for ListDeviceCapabilities", + "file": "admanager_v1_generated_device_capability_service_list_device_capabilities_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_DeviceCapabilityService_ListDeviceCapabilities_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_device_capability_service_list_device_capabilities_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.DeviceCategoryServiceClient", + "shortName": "DeviceCategoryServiceClient" + }, + "fullName": "google.ads.admanager_v1.DeviceCategoryServiceClient.get_device_category", + "method": { + "fullName": "google.ads.admanager.v1.DeviceCategoryService.GetDeviceCategory", + "service": { + "fullName": "google.ads.admanager.v1.DeviceCategoryService", + "shortName": "DeviceCategoryService" + }, + "shortName": "GetDeviceCategory" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.GetDeviceCategoryRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.DeviceCategory", + "shortName": "get_device_category" + }, + "description": "Sample for GetDeviceCategory", + "file": "admanager_v1_generated_device_category_service_get_device_category_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_DeviceCategoryService_GetDeviceCategory_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_device_category_service_get_device_category_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.DeviceCategoryServiceClient", + "shortName": "DeviceCategoryServiceClient" + }, + "fullName": "google.ads.admanager_v1.DeviceCategoryServiceClient.list_device_categories", + "method": { + "fullName": "google.ads.admanager.v1.DeviceCategoryService.ListDeviceCategories", + "service": { + "fullName": "google.ads.admanager.v1.DeviceCategoryService", + "shortName": "DeviceCategoryService" + }, + "shortName": "ListDeviceCategories" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.ListDeviceCategoriesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.services.device_category_service.pagers.ListDeviceCategoriesPager", + "shortName": "list_device_categories" + }, + "description": "Sample for ListDeviceCategories", + "file": "admanager_v1_generated_device_category_service_list_device_categories_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_DeviceCategoryService_ListDeviceCategories_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_device_category_service_list_device_categories_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.DeviceManufacturerServiceClient", + "shortName": "DeviceManufacturerServiceClient" + }, + "fullName": "google.ads.admanager_v1.DeviceManufacturerServiceClient.get_device_manufacturer", + "method": { + "fullName": "google.ads.admanager.v1.DeviceManufacturerService.GetDeviceManufacturer", + "service": { + "fullName": "google.ads.admanager.v1.DeviceManufacturerService", + "shortName": "DeviceManufacturerService" + }, + "shortName": "GetDeviceManufacturer" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.GetDeviceManufacturerRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.DeviceManufacturer", + "shortName": "get_device_manufacturer" + }, + "description": "Sample for GetDeviceManufacturer", + "file": "admanager_v1_generated_device_manufacturer_service_get_device_manufacturer_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_DeviceManufacturerService_GetDeviceManufacturer_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_device_manufacturer_service_get_device_manufacturer_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.DeviceManufacturerServiceClient", + "shortName": "DeviceManufacturerServiceClient" + }, + "fullName": "google.ads.admanager_v1.DeviceManufacturerServiceClient.list_device_manufacturers", + "method": { + "fullName": "google.ads.admanager.v1.DeviceManufacturerService.ListDeviceManufacturers", + "service": { + "fullName": "google.ads.admanager.v1.DeviceManufacturerService", + "shortName": "DeviceManufacturerService" + }, + "shortName": "ListDeviceManufacturers" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.ListDeviceManufacturersRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.services.device_manufacturer_service.pagers.ListDeviceManufacturersPager", + "shortName": "list_device_manufacturers" + }, + "description": "Sample for ListDeviceManufacturers", + "file": "admanager_v1_generated_device_manufacturer_service_list_device_manufacturers_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_DeviceManufacturerService_ListDeviceManufacturers_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_device_manufacturer_service_list_device_manufacturers_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient", + "shortName": "EntitySignalsMappingServiceClient" + }, + "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient.batch_create_entity_signals_mappings", + "method": { + "fullName": "google.ads.admanager.v1.EntitySignalsMappingService.BatchCreateEntitySignalsMappings", + "service": { + "fullName": "google.ads.admanager.v1.EntitySignalsMappingService", + "shortName": "EntitySignalsMappingService" + }, + "shortName": "BatchCreateEntitySignalsMappings" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.BatchCreateEntitySignalsMappingsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "requests", + "type": "MutableSequence[google.ads.admanager_v1.types.CreateEntitySignalsMappingRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.BatchCreateEntitySignalsMappingsResponse", + "shortName": "batch_create_entity_signals_mappings" + }, + "description": "Sample for BatchCreateEntitySignalsMappings", + "file": "admanager_v1_generated_entity_signals_mapping_service_batch_create_entity_signals_mappings_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_EntitySignalsMappingService_BatchCreateEntitySignalsMappings_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_entity_signals_mapping_service_batch_create_entity_signals_mappings_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient", + "shortName": "EntitySignalsMappingServiceClient" + }, + "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient.batch_update_entity_signals_mappings", + "method": { + "fullName": "google.ads.admanager.v1.EntitySignalsMappingService.BatchUpdateEntitySignalsMappings", + "service": { + "fullName": "google.ads.admanager.v1.EntitySignalsMappingService", + "shortName": "EntitySignalsMappingService" + }, + "shortName": "BatchUpdateEntitySignalsMappings" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.BatchUpdateEntitySignalsMappingsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "requests", + "type": "MutableSequence[google.ads.admanager_v1.types.UpdateEntitySignalsMappingRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.BatchUpdateEntitySignalsMappingsResponse", + "shortName": "batch_update_entity_signals_mappings" + }, + "description": "Sample for BatchUpdateEntitySignalsMappings", + "file": "admanager_v1_generated_entity_signals_mapping_service_batch_update_entity_signals_mappings_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_EntitySignalsMappingService_BatchUpdateEntitySignalsMappings_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_entity_signals_mapping_service_batch_update_entity_signals_mappings_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient", + "shortName": "EntitySignalsMappingServiceClient" + }, + "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient.create_entity_signals_mapping", + "method": { + "fullName": "google.ads.admanager.v1.EntitySignalsMappingService.CreateEntitySignalsMapping", + "service": { + "fullName": "google.ads.admanager.v1.EntitySignalsMappingService", + "shortName": "EntitySignalsMappingService" + }, + "shortName": "CreateEntitySignalsMapping" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.CreateEntitySignalsMappingRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "entity_signals_mapping", + "type": "google.ads.admanager_v1.types.EntitySignalsMapping" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.EntitySignalsMapping", + "shortName": "create_entity_signals_mapping" + }, + "description": "Sample for CreateEntitySignalsMapping", + "file": "admanager_v1_generated_entity_signals_mapping_service_create_entity_signals_mapping_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_EntitySignalsMappingService_CreateEntitySignalsMapping_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_entity_signals_mapping_service_create_entity_signals_mapping_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient", + "shortName": "EntitySignalsMappingServiceClient" + }, + "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient.get_entity_signals_mapping", + "method": { + "fullName": "google.ads.admanager.v1.EntitySignalsMappingService.GetEntitySignalsMapping", + "service": { + "fullName": "google.ads.admanager.v1.EntitySignalsMappingService", + "shortName": "EntitySignalsMappingService" + }, + "shortName": "GetEntitySignalsMapping" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.GetEntitySignalsMappingRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.EntitySignalsMapping", + "shortName": "get_entity_signals_mapping" + }, + "description": "Sample for GetEntitySignalsMapping", + "file": "admanager_v1_generated_entity_signals_mapping_service_get_entity_signals_mapping_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_EntitySignalsMappingService_GetEntitySignalsMapping_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_entity_signals_mapping_service_get_entity_signals_mapping_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient", + "shortName": "EntitySignalsMappingServiceClient" + }, + "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient.list_entity_signals_mappings", + "method": { + "fullName": "google.ads.admanager.v1.EntitySignalsMappingService.ListEntitySignalsMappings", + "service": { + "fullName": "google.ads.admanager.v1.EntitySignalsMappingService", + "shortName": "EntitySignalsMappingService" + }, + "shortName": "ListEntitySignalsMappings" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.ListEntitySignalsMappingsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.services.entity_signals_mapping_service.pagers.ListEntitySignalsMappingsPager", + "shortName": "list_entity_signals_mappings" + }, + "description": "Sample for ListEntitySignalsMappings", + "file": "admanager_v1_generated_entity_signals_mapping_service_list_entity_signals_mappings_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_EntitySignalsMappingService_ListEntitySignalsMappings_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_entity_signals_mapping_service_list_entity_signals_mappings_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient", + "shortName": "EntitySignalsMappingServiceClient" + }, + "fullName": "google.ads.admanager_v1.EntitySignalsMappingServiceClient.update_entity_signals_mapping", + "method": { + "fullName": "google.ads.admanager.v1.EntitySignalsMappingService.UpdateEntitySignalsMapping", + "service": { + "fullName": "google.ads.admanager.v1.EntitySignalsMappingService", + "shortName": "EntitySignalsMappingService" + }, + "shortName": "UpdateEntitySignalsMapping" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.UpdateEntitySignalsMappingRequest" + }, + { + "name": "entity_signals_mapping", + "type": "google.ads.admanager_v1.types.EntitySignalsMapping" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.EntitySignalsMapping", + "shortName": "update_entity_signals_mapping" + }, + "description": "Sample for UpdateEntitySignalsMapping", + "file": "admanager_v1_generated_entity_signals_mapping_service_update_entity_signals_mapping_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_EntitySignalsMappingService_UpdateEntitySignalsMapping_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_entity_signals_mapping_service_update_entity_signals_mapping_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.GeoTargetServiceClient", + "shortName": "GeoTargetServiceClient" + }, + "fullName": "google.ads.admanager_v1.GeoTargetServiceClient.get_geo_target", + "method": { + "fullName": "google.ads.admanager.v1.GeoTargetService.GetGeoTarget", + "service": { + "fullName": "google.ads.admanager.v1.GeoTargetService", + "shortName": "GeoTargetService" + }, + "shortName": "GetGeoTarget" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.GetGeoTargetRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.GeoTarget", + "shortName": "get_geo_target" + }, + "description": "Sample for GetGeoTarget", + "file": "admanager_v1_generated_geo_target_service_get_geo_target_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_GeoTargetService_GetGeoTarget_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_geo_target_service_get_geo_target_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.GeoTargetServiceClient", + "shortName": "GeoTargetServiceClient" + }, + "fullName": "google.ads.admanager_v1.GeoTargetServiceClient.list_geo_targets", + "method": { + "fullName": "google.ads.admanager.v1.GeoTargetService.ListGeoTargets", + "service": { + "fullName": "google.ads.admanager.v1.GeoTargetService", + "shortName": "GeoTargetService" + }, + "shortName": "ListGeoTargets" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.ListGeoTargetsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.services.geo_target_service.pagers.ListGeoTargetsPager", + "shortName": "list_geo_targets" + }, + "description": "Sample for ListGeoTargets", + "file": "admanager_v1_generated_geo_target_service_list_geo_targets_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_GeoTargetService_ListGeoTargets_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_geo_target_service_list_geo_targets_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.MobileCarrierServiceClient", + "shortName": "MobileCarrierServiceClient" + }, + "fullName": "google.ads.admanager_v1.MobileCarrierServiceClient.get_mobile_carrier", + "method": { + "fullName": "google.ads.admanager.v1.MobileCarrierService.GetMobileCarrier", + "service": { + "fullName": "google.ads.admanager.v1.MobileCarrierService", + "shortName": "MobileCarrierService" + }, + "shortName": "GetMobileCarrier" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.GetMobileCarrierRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.MobileCarrier", + "shortName": "get_mobile_carrier" + }, + "description": "Sample for GetMobileCarrier", + "file": "admanager_v1_generated_mobile_carrier_service_get_mobile_carrier_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_MobileCarrierService_GetMobileCarrier_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_mobile_carrier_service_get_mobile_carrier_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.MobileCarrierServiceClient", + "shortName": "MobileCarrierServiceClient" + }, + "fullName": "google.ads.admanager_v1.MobileCarrierServiceClient.list_mobile_carriers", + "method": { + "fullName": "google.ads.admanager.v1.MobileCarrierService.ListMobileCarriers", + "service": { + "fullName": "google.ads.admanager.v1.MobileCarrierService", + "shortName": "MobileCarrierService" + }, + "shortName": "ListMobileCarriers" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.ListMobileCarriersRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.services.mobile_carrier_service.pagers.ListMobileCarriersPager", + "shortName": "list_mobile_carriers" + }, + "description": "Sample for ListMobileCarriers", + "file": "admanager_v1_generated_mobile_carrier_service_list_mobile_carriers_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_MobileCarrierService_ListMobileCarriers_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_mobile_carrier_service_list_mobile_carriers_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.MobileDeviceServiceClient", + "shortName": "MobileDeviceServiceClient" + }, + "fullName": "google.ads.admanager_v1.MobileDeviceServiceClient.get_mobile_device", + "method": { + "fullName": "google.ads.admanager.v1.MobileDeviceService.GetMobileDevice", + "service": { + "fullName": "google.ads.admanager.v1.MobileDeviceService", + "shortName": "MobileDeviceService" + }, + "shortName": "GetMobileDevice" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.GetMobileDeviceRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.MobileDevice", + "shortName": "get_mobile_device" + }, + "description": "Sample for GetMobileDevice", + "file": "admanager_v1_generated_mobile_device_service_get_mobile_device_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_MobileDeviceService_GetMobileDevice_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_mobile_device_service_get_mobile_device_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.MobileDeviceServiceClient", + "shortName": "MobileDeviceServiceClient" + }, + "fullName": "google.ads.admanager_v1.MobileDeviceServiceClient.list_mobile_devices", + "method": { + "fullName": "google.ads.admanager.v1.MobileDeviceService.ListMobileDevices", + "service": { + "fullName": "google.ads.admanager.v1.MobileDeviceService", + "shortName": "MobileDeviceService" + }, + "shortName": "ListMobileDevices" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.ListMobileDevicesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.services.mobile_device_service.pagers.ListMobileDevicesPager", + "shortName": "list_mobile_devices" + }, + "description": "Sample for ListMobileDevices", + "file": "admanager_v1_generated_mobile_device_service_list_mobile_devices_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_MobileDeviceService_ListMobileDevices_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_mobile_device_service_list_mobile_devices_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.MobileDeviceSubmodelServiceClient", + "shortName": "MobileDeviceSubmodelServiceClient" + }, + "fullName": "google.ads.admanager_v1.MobileDeviceSubmodelServiceClient.get_mobile_device_submodel", + "method": { + "fullName": "google.ads.admanager.v1.MobileDeviceSubmodelService.GetMobileDeviceSubmodel", + "service": { + "fullName": "google.ads.admanager.v1.MobileDeviceSubmodelService", + "shortName": "MobileDeviceSubmodelService" + }, + "shortName": "GetMobileDeviceSubmodel" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.GetMobileDeviceSubmodelRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.MobileDeviceSubmodel", + "shortName": "get_mobile_device_submodel" + }, + "description": "Sample for GetMobileDeviceSubmodel", + "file": "admanager_v1_generated_mobile_device_submodel_service_get_mobile_device_submodel_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_MobileDeviceSubmodelService_GetMobileDeviceSubmodel_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_mobile_device_submodel_service_get_mobile_device_submodel_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.MobileDeviceSubmodelServiceClient", + "shortName": "MobileDeviceSubmodelServiceClient" + }, + "fullName": "google.ads.admanager_v1.MobileDeviceSubmodelServiceClient.list_mobile_device_submodels", + "method": { + "fullName": "google.ads.admanager.v1.MobileDeviceSubmodelService.ListMobileDeviceSubmodels", + "service": { + "fullName": "google.ads.admanager.v1.MobileDeviceSubmodelService", + "shortName": "MobileDeviceSubmodelService" + }, + "shortName": "ListMobileDeviceSubmodels" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.ListMobileDeviceSubmodelsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.services.mobile_device_submodel_service.pagers.ListMobileDeviceSubmodelsPager", + "shortName": "list_mobile_device_submodels" + }, + "description": "Sample for ListMobileDeviceSubmodels", + "file": "admanager_v1_generated_mobile_device_submodel_service_list_mobile_device_submodels_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_MobileDeviceSubmodelService_ListMobileDeviceSubmodels_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_mobile_device_submodel_service_list_mobile_device_submodels_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.NetworkServiceClient", + "shortName": "NetworkServiceClient" + }, + "fullName": "google.ads.admanager_v1.NetworkServiceClient.get_network", + "method": { + "fullName": "google.ads.admanager.v1.NetworkService.GetNetwork", + "service": { + "fullName": "google.ads.admanager.v1.NetworkService", + "shortName": "NetworkService" + }, + "shortName": "GetNetwork" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.GetNetworkRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.Network", + "shortName": "get_network" + }, + "description": "Sample for GetNetwork", + "file": "admanager_v1_generated_network_service_get_network_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_NetworkService_GetNetwork_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_network_service_get_network_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.NetworkServiceClient", + "shortName": "NetworkServiceClient" + }, + "fullName": "google.ads.admanager_v1.NetworkServiceClient.list_networks", + "method": { + "fullName": "google.ads.admanager.v1.NetworkService.ListNetworks", + "service": { + "fullName": "google.ads.admanager.v1.NetworkService", + "shortName": "NetworkService" + }, + "shortName": "ListNetworks" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.ListNetworksRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.ListNetworksResponse", + "shortName": "list_networks" + }, + "description": "Sample for ListNetworks", + "file": "admanager_v1_generated_network_service_list_networks_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_NetworkService_ListNetworks_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_network_service_list_networks_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.OperatingSystemServiceClient", + "shortName": "OperatingSystemServiceClient" + }, + "fullName": "google.ads.admanager_v1.OperatingSystemServiceClient.get_operating_system", + "method": { + "fullName": "google.ads.admanager.v1.OperatingSystemService.GetOperatingSystem", + "service": { + "fullName": "google.ads.admanager.v1.OperatingSystemService", + "shortName": "OperatingSystemService" + }, + "shortName": "GetOperatingSystem" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.GetOperatingSystemRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.OperatingSystem", + "shortName": "get_operating_system" + }, + "description": "Sample for GetOperatingSystem", + "file": "admanager_v1_generated_operating_system_service_get_operating_system_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_OperatingSystemService_GetOperatingSystem_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_operating_system_service_get_operating_system_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.OperatingSystemServiceClient", + "shortName": "OperatingSystemServiceClient" + }, + "fullName": "google.ads.admanager_v1.OperatingSystemServiceClient.list_operating_systems", + "method": { + "fullName": "google.ads.admanager.v1.OperatingSystemService.ListOperatingSystems", + "service": { + "fullName": "google.ads.admanager.v1.OperatingSystemService", + "shortName": "OperatingSystemService" + }, + "shortName": "ListOperatingSystems" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.ListOperatingSystemsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.services.operating_system_service.pagers.ListOperatingSystemsPager", + "shortName": "list_operating_systems" + }, + "description": "Sample for ListOperatingSystems", + "file": "admanager_v1_generated_operating_system_service_list_operating_systems_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_OperatingSystemService_ListOperatingSystems_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_operating_system_service_list_operating_systems_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.OperatingSystemVersionServiceClient", + "shortName": "OperatingSystemVersionServiceClient" + }, + "fullName": "google.ads.admanager_v1.OperatingSystemVersionServiceClient.get_operating_system_version", + "method": { + "fullName": "google.ads.admanager.v1.OperatingSystemVersionService.GetOperatingSystemVersion", + "service": { + "fullName": "google.ads.admanager.v1.OperatingSystemVersionService", + "shortName": "OperatingSystemVersionService" + }, + "shortName": "GetOperatingSystemVersion" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.GetOperatingSystemVersionRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.OperatingSystemVersion", + "shortName": "get_operating_system_version" + }, + "description": "Sample for GetOperatingSystemVersion", + "file": "admanager_v1_generated_operating_system_version_service_get_operating_system_version_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_OperatingSystemVersionService_GetOperatingSystemVersion_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_operating_system_version_service_get_operating_system_version_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.OperatingSystemVersionServiceClient", + "shortName": "OperatingSystemVersionServiceClient" + }, + "fullName": "google.ads.admanager_v1.OperatingSystemVersionServiceClient.list_operating_system_versions", + "method": { + "fullName": "google.ads.admanager.v1.OperatingSystemVersionService.ListOperatingSystemVersions", + "service": { + "fullName": "google.ads.admanager.v1.OperatingSystemVersionService", + "shortName": "OperatingSystemVersionService" + }, + "shortName": "ListOperatingSystemVersions" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.ListOperatingSystemVersionsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.services.operating_system_version_service.pagers.ListOperatingSystemVersionsPager", + "shortName": "list_operating_system_versions" + }, + "description": "Sample for ListOperatingSystemVersions", + "file": "admanager_v1_generated_operating_system_version_service_list_operating_system_versions_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_OperatingSystemVersionService_ListOperatingSystemVersions_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_operating_system_version_service_list_operating_system_versions_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.OrderServiceClient", + "shortName": "OrderServiceClient" + }, + "fullName": "google.ads.admanager_v1.OrderServiceClient.get_order", + "method": { + "fullName": "google.ads.admanager.v1.OrderService.GetOrder", + "service": { + "fullName": "google.ads.admanager.v1.OrderService", + "shortName": "OrderService" + }, + "shortName": "GetOrder" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.GetOrderRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.Order", + "shortName": "get_order" + }, + "description": "Sample for GetOrder", + "file": "admanager_v1_generated_order_service_get_order_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_OrderService_GetOrder_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_order_service_get_order_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.OrderServiceClient", + "shortName": "OrderServiceClient" + }, + "fullName": "google.ads.admanager_v1.OrderServiceClient.list_orders", + "method": { + "fullName": "google.ads.admanager.v1.OrderService.ListOrders", + "service": { + "fullName": "google.ads.admanager.v1.OrderService", + "shortName": "OrderService" + }, + "shortName": "ListOrders" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.ListOrdersRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.services.order_service.pagers.ListOrdersPager", + "shortName": "list_orders" + }, + "description": "Sample for ListOrders", + "file": "admanager_v1_generated_order_service_list_orders_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_OrderService_ListOrders_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_order_service_list_orders_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.PlacementServiceClient", + "shortName": "PlacementServiceClient" + }, + "fullName": "google.ads.admanager_v1.PlacementServiceClient.batch_activate_placements", + "method": { + "fullName": "google.ads.admanager.v1.PlacementService.BatchActivatePlacements", + "service": { + "fullName": "google.ads.admanager.v1.PlacementService", + "shortName": "PlacementService" + }, + "shortName": "BatchActivatePlacements" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.BatchActivatePlacementsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "names", + "type": "MutableSequence[str]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.BatchActivatePlacementsResponse", + "shortName": "batch_activate_placements" + }, + "description": "Sample for BatchActivatePlacements", + "file": "admanager_v1_generated_placement_service_batch_activate_placements_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_PlacementService_BatchActivatePlacements_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_placement_service_batch_activate_placements_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.PlacementServiceClient", + "shortName": "PlacementServiceClient" + }, + "fullName": "google.ads.admanager_v1.PlacementServiceClient.batch_archive_placements", + "method": { + "fullName": "google.ads.admanager.v1.PlacementService.BatchArchivePlacements", + "service": { + "fullName": "google.ads.admanager.v1.PlacementService", + "shortName": "PlacementService" + }, + "shortName": "BatchArchivePlacements" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.BatchArchivePlacementsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "names", + "type": "MutableSequence[str]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.BatchArchivePlacementsResponse", + "shortName": "batch_archive_placements" + }, + "description": "Sample for BatchArchivePlacements", + "file": "admanager_v1_generated_placement_service_batch_archive_placements_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_PlacementService_BatchArchivePlacements_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_placement_service_batch_archive_placements_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.PlacementServiceClient", + "shortName": "PlacementServiceClient" + }, + "fullName": "google.ads.admanager_v1.PlacementServiceClient.batch_create_placements", + "method": { + "fullName": "google.ads.admanager.v1.PlacementService.BatchCreatePlacements", + "service": { + "fullName": "google.ads.admanager.v1.PlacementService", + "shortName": "PlacementService" + }, + "shortName": "BatchCreatePlacements" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.BatchCreatePlacementsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "requests", + "type": "MutableSequence[google.ads.admanager_v1.types.CreatePlacementRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.BatchCreatePlacementsResponse", + "shortName": "batch_create_placements" + }, + "description": "Sample for BatchCreatePlacements", + "file": "admanager_v1_generated_placement_service_batch_create_placements_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_PlacementService_BatchCreatePlacements_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_placement_service_batch_create_placements_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.PlacementServiceClient", + "shortName": "PlacementServiceClient" + }, + "fullName": "google.ads.admanager_v1.PlacementServiceClient.batch_deactivate_placements", + "method": { + "fullName": "google.ads.admanager.v1.PlacementService.BatchDeactivatePlacements", + "service": { + "fullName": "google.ads.admanager.v1.PlacementService", + "shortName": "PlacementService" + }, + "shortName": "BatchDeactivatePlacements" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.BatchDeactivatePlacementsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "names", + "type": "MutableSequence[str]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.BatchDeactivatePlacementsResponse", + "shortName": "batch_deactivate_placements" + }, + "description": "Sample for BatchDeactivatePlacements", + "file": "admanager_v1_generated_placement_service_batch_deactivate_placements_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_PlacementService_BatchDeactivatePlacements_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_placement_service_batch_deactivate_placements_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.PlacementServiceClient", + "shortName": "PlacementServiceClient" + }, + "fullName": "google.ads.admanager_v1.PlacementServiceClient.batch_update_placements", + "method": { + "fullName": "google.ads.admanager.v1.PlacementService.BatchUpdatePlacements", + "service": { + "fullName": "google.ads.admanager.v1.PlacementService", + "shortName": "PlacementService" + }, + "shortName": "BatchUpdatePlacements" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.BatchUpdatePlacementsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "requests", + "type": "MutableSequence[google.ads.admanager_v1.types.UpdatePlacementRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.BatchUpdatePlacementsResponse", + "shortName": "batch_update_placements" + }, + "description": "Sample for BatchUpdatePlacements", + "file": "admanager_v1_generated_placement_service_batch_update_placements_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_PlacementService_BatchUpdatePlacements_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_placement_service_batch_update_placements_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.PlacementServiceClient", + "shortName": "PlacementServiceClient" + }, + "fullName": "google.ads.admanager_v1.PlacementServiceClient.create_placement", + "method": { + "fullName": "google.ads.admanager.v1.PlacementService.CreatePlacement", + "service": { + "fullName": "google.ads.admanager.v1.PlacementService", + "shortName": "PlacementService" + }, + "shortName": "CreatePlacement" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.CreatePlacementRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "placement", + "type": "google.ads.admanager_v1.types.Placement" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.Placement", + "shortName": "create_placement" + }, + "description": "Sample for CreatePlacement", + "file": "admanager_v1_generated_placement_service_create_placement_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_PlacementService_CreatePlacement_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_placement_service_create_placement_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.PlacementServiceClient", + "shortName": "PlacementServiceClient" + }, + "fullName": "google.ads.admanager_v1.PlacementServiceClient.get_placement", + "method": { + "fullName": "google.ads.admanager.v1.PlacementService.GetPlacement", + "service": { + "fullName": "google.ads.admanager.v1.PlacementService", + "shortName": "PlacementService" + }, + "shortName": "GetPlacement" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.GetPlacementRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.Placement", + "shortName": "get_placement" + }, + "description": "Sample for GetPlacement", + "file": "admanager_v1_generated_placement_service_get_placement_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_PlacementService_GetPlacement_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_placement_service_get_placement_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.PlacementServiceClient", + "shortName": "PlacementServiceClient" + }, + "fullName": "google.ads.admanager_v1.PlacementServiceClient.list_placements", + "method": { + "fullName": "google.ads.admanager.v1.PlacementService.ListPlacements", + "service": { + "fullName": "google.ads.admanager.v1.PlacementService", + "shortName": "PlacementService" + }, + "shortName": "ListPlacements" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.ListPlacementsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.services.placement_service.pagers.ListPlacementsPager", + "shortName": "list_placements" + }, + "description": "Sample for ListPlacements", + "file": "admanager_v1_generated_placement_service_list_placements_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_PlacementService_ListPlacements_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_placement_service_list_placements_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.PlacementServiceClient", + "shortName": "PlacementServiceClient" + }, + "fullName": "google.ads.admanager_v1.PlacementServiceClient.update_placement", + "method": { + "fullName": "google.ads.admanager.v1.PlacementService.UpdatePlacement", + "service": { + "fullName": "google.ads.admanager.v1.PlacementService", + "shortName": "PlacementService" + }, + "shortName": "UpdatePlacement" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.UpdatePlacementRequest" + }, + { + "name": "placement", + "type": "google.ads.admanager_v1.types.Placement" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.Placement", + "shortName": "update_placement" + }, + "description": "Sample for UpdatePlacement", + "file": "admanager_v1_generated_placement_service_update_placement_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_PlacementService_UpdatePlacement_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_placement_service_update_placement_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.PrivateAuctionDealServiceClient", + "shortName": "PrivateAuctionDealServiceClient" + }, + "fullName": "google.ads.admanager_v1.PrivateAuctionDealServiceClient.create_private_auction_deal", + "method": { + "fullName": "google.ads.admanager.v1.PrivateAuctionDealService.CreatePrivateAuctionDeal", + "service": { + "fullName": "google.ads.admanager.v1.PrivateAuctionDealService", + "shortName": "PrivateAuctionDealService" + }, + "shortName": "CreatePrivateAuctionDeal" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.CreatePrivateAuctionDealRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "private_auction_deal", + "type": "google.ads.admanager_v1.types.PrivateAuctionDeal" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.PrivateAuctionDeal", + "shortName": "create_private_auction_deal" + }, + "description": "Sample for CreatePrivateAuctionDeal", + "file": "admanager_v1_generated_private_auction_deal_service_create_private_auction_deal_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_PrivateAuctionDealService_CreatePrivateAuctionDeal_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_private_auction_deal_service_create_private_auction_deal_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.PrivateAuctionDealServiceClient", + "shortName": "PrivateAuctionDealServiceClient" + }, + "fullName": "google.ads.admanager_v1.PrivateAuctionDealServiceClient.get_private_auction_deal", + "method": { + "fullName": "google.ads.admanager.v1.PrivateAuctionDealService.GetPrivateAuctionDeal", + "service": { + "fullName": "google.ads.admanager.v1.PrivateAuctionDealService", + "shortName": "PrivateAuctionDealService" + }, + "shortName": "GetPrivateAuctionDeal" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.GetPrivateAuctionDealRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.PrivateAuctionDeal", + "shortName": "get_private_auction_deal" + }, + "description": "Sample for GetPrivateAuctionDeal", + "file": "admanager_v1_generated_private_auction_deal_service_get_private_auction_deal_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_PrivateAuctionDealService_GetPrivateAuctionDeal_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_private_auction_deal_service_get_private_auction_deal_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.PrivateAuctionDealServiceClient", + "shortName": "PrivateAuctionDealServiceClient" + }, + "fullName": "google.ads.admanager_v1.PrivateAuctionDealServiceClient.list_private_auction_deals", + "method": { + "fullName": "google.ads.admanager.v1.PrivateAuctionDealService.ListPrivateAuctionDeals", + "service": { + "fullName": "google.ads.admanager.v1.PrivateAuctionDealService", + "shortName": "PrivateAuctionDealService" + }, + "shortName": "ListPrivateAuctionDeals" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.ListPrivateAuctionDealsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.services.private_auction_deal_service.pagers.ListPrivateAuctionDealsPager", + "shortName": "list_private_auction_deals" + }, + "description": "Sample for ListPrivateAuctionDeals", + "file": "admanager_v1_generated_private_auction_deal_service_list_private_auction_deals_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_PrivateAuctionDealService_ListPrivateAuctionDeals_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_private_auction_deal_service_list_private_auction_deals_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.PrivateAuctionDealServiceClient", + "shortName": "PrivateAuctionDealServiceClient" + }, + "fullName": "google.ads.admanager_v1.PrivateAuctionDealServiceClient.update_private_auction_deal", + "method": { + "fullName": "google.ads.admanager.v1.PrivateAuctionDealService.UpdatePrivateAuctionDeal", + "service": { + "fullName": "google.ads.admanager.v1.PrivateAuctionDealService", + "shortName": "PrivateAuctionDealService" + }, + "shortName": "UpdatePrivateAuctionDeal" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.UpdatePrivateAuctionDealRequest" + }, + { + "name": "private_auction_deal", + "type": "google.ads.admanager_v1.types.PrivateAuctionDeal" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.PrivateAuctionDeal", + "shortName": "update_private_auction_deal" + }, + "description": "Sample for UpdatePrivateAuctionDeal", + "file": "admanager_v1_generated_private_auction_deal_service_update_private_auction_deal_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_PrivateAuctionDealService_UpdatePrivateAuctionDeal_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_private_auction_deal_service_update_private_auction_deal_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.PrivateAuctionServiceClient", + "shortName": "PrivateAuctionServiceClient" + }, + "fullName": "google.ads.admanager_v1.PrivateAuctionServiceClient.create_private_auction", + "method": { + "fullName": "google.ads.admanager.v1.PrivateAuctionService.CreatePrivateAuction", + "service": { + "fullName": "google.ads.admanager.v1.PrivateAuctionService", + "shortName": "PrivateAuctionService" + }, + "shortName": "CreatePrivateAuction" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.CreatePrivateAuctionRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "private_auction", + "type": "google.ads.admanager_v1.types.PrivateAuction" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.PrivateAuction", + "shortName": "create_private_auction" + }, + "description": "Sample for CreatePrivateAuction", + "file": "admanager_v1_generated_private_auction_service_create_private_auction_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_PrivateAuctionService_CreatePrivateAuction_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_private_auction_service_create_private_auction_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.PrivateAuctionServiceClient", + "shortName": "PrivateAuctionServiceClient" + }, + "fullName": "google.ads.admanager_v1.PrivateAuctionServiceClient.get_private_auction", + "method": { + "fullName": "google.ads.admanager.v1.PrivateAuctionService.GetPrivateAuction", + "service": { + "fullName": "google.ads.admanager.v1.PrivateAuctionService", + "shortName": "PrivateAuctionService" + }, + "shortName": "GetPrivateAuction" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.GetPrivateAuctionRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.PrivateAuction", + "shortName": "get_private_auction" + }, + "description": "Sample for GetPrivateAuction", + "file": "admanager_v1_generated_private_auction_service_get_private_auction_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_PrivateAuctionService_GetPrivateAuction_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, "type": "RESPONSE_HANDLING" } ], @@ -3564,27 +7792,1255 @@ "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.PrivateAuctionServiceClient", - "shortName": "PrivateAuctionServiceClient" + "fullName": "google.ads.admanager_v1.PrivateAuctionServiceClient", + "shortName": "PrivateAuctionServiceClient" + }, + "fullName": "google.ads.admanager_v1.PrivateAuctionServiceClient.list_private_auctions", + "method": { + "fullName": "google.ads.admanager.v1.PrivateAuctionService.ListPrivateAuctions", + "service": { + "fullName": "google.ads.admanager.v1.PrivateAuctionService", + "shortName": "PrivateAuctionService" + }, + "shortName": "ListPrivateAuctions" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.ListPrivateAuctionsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.services.private_auction_service.pagers.ListPrivateAuctionsPager", + "shortName": "list_private_auctions" + }, + "description": "Sample for ListPrivateAuctions", + "file": "admanager_v1_generated_private_auction_service_list_private_auctions_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_PrivateAuctionService_ListPrivateAuctions_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_private_auction_service_list_private_auctions_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.PrivateAuctionServiceClient", + "shortName": "PrivateAuctionServiceClient" + }, + "fullName": "google.ads.admanager_v1.PrivateAuctionServiceClient.update_private_auction", + "method": { + "fullName": "google.ads.admanager.v1.PrivateAuctionService.UpdatePrivateAuction", + "service": { + "fullName": "google.ads.admanager.v1.PrivateAuctionService", + "shortName": "PrivateAuctionService" + }, + "shortName": "UpdatePrivateAuction" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.UpdatePrivateAuctionRequest" + }, + { + "name": "private_auction", + "type": "google.ads.admanager_v1.types.PrivateAuction" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.PrivateAuction", + "shortName": "update_private_auction" + }, + "description": "Sample for UpdatePrivateAuction", + "file": "admanager_v1_generated_private_auction_service_update_private_auction_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_PrivateAuctionService_UpdatePrivateAuction_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_private_auction_service_update_private_auction_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.ProgrammaticBuyerServiceClient", + "shortName": "ProgrammaticBuyerServiceClient" + }, + "fullName": "google.ads.admanager_v1.ProgrammaticBuyerServiceClient.get_programmatic_buyer", + "method": { + "fullName": "google.ads.admanager.v1.ProgrammaticBuyerService.GetProgrammaticBuyer", + "service": { + "fullName": "google.ads.admanager.v1.ProgrammaticBuyerService", + "shortName": "ProgrammaticBuyerService" + }, + "shortName": "GetProgrammaticBuyer" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.GetProgrammaticBuyerRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.ProgrammaticBuyer", + "shortName": "get_programmatic_buyer" + }, + "description": "Sample for GetProgrammaticBuyer", + "file": "admanager_v1_generated_programmatic_buyer_service_get_programmatic_buyer_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_ProgrammaticBuyerService_GetProgrammaticBuyer_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_programmatic_buyer_service_get_programmatic_buyer_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.ProgrammaticBuyerServiceClient", + "shortName": "ProgrammaticBuyerServiceClient" + }, + "fullName": "google.ads.admanager_v1.ProgrammaticBuyerServiceClient.list_programmatic_buyers", + "method": { + "fullName": "google.ads.admanager.v1.ProgrammaticBuyerService.ListProgrammaticBuyers", + "service": { + "fullName": "google.ads.admanager.v1.ProgrammaticBuyerService", + "shortName": "ProgrammaticBuyerService" + }, + "shortName": "ListProgrammaticBuyers" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.ListProgrammaticBuyersRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.services.programmatic_buyer_service.pagers.ListProgrammaticBuyersPager", + "shortName": "list_programmatic_buyers" + }, + "description": "Sample for ListProgrammaticBuyers", + "file": "admanager_v1_generated_programmatic_buyer_service_list_programmatic_buyers_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_ProgrammaticBuyerService_ListProgrammaticBuyers_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_programmatic_buyer_service_list_programmatic_buyers_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.ReportServiceClient", + "shortName": "ReportServiceClient" + }, + "fullName": "google.ads.admanager_v1.ReportServiceClient.create_report", + "method": { + "fullName": "google.ads.admanager.v1.ReportService.CreateReport", + "service": { + "fullName": "google.ads.admanager.v1.ReportService", + "shortName": "ReportService" + }, + "shortName": "CreateReport" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.CreateReportRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "report", + "type": "google.ads.admanager_v1.types.Report" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.Report", + "shortName": "create_report" + }, + "description": "Sample for CreateReport", + "file": "admanager_v1_generated_report_service_create_report_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_ReportService_CreateReport_sync", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 51, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 52, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_report_service_create_report_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.ReportServiceClient", + "shortName": "ReportServiceClient" + }, + "fullName": "google.ads.admanager_v1.ReportServiceClient.fetch_report_result_rows", + "method": { + "fullName": "google.ads.admanager.v1.ReportService.FetchReportResultRows", + "service": { + "fullName": "google.ads.admanager.v1.ReportService", + "shortName": "ReportService" + }, + "shortName": "FetchReportResultRows" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.FetchReportResultRowsRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.services.report_service.pagers.FetchReportResultRowsPager", + "shortName": "fetch_report_result_rows" + }, + "description": "Sample for FetchReportResultRows", + "file": "admanager_v1_generated_report_service_fetch_report_result_rows_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_ReportService_FetchReportResultRows_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_report_service_fetch_report_result_rows_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.ReportServiceClient", + "shortName": "ReportServiceClient" + }, + "fullName": "google.ads.admanager_v1.ReportServiceClient.get_report", + "method": { + "fullName": "google.ads.admanager.v1.ReportService.GetReport", + "service": { + "fullName": "google.ads.admanager.v1.ReportService", + "shortName": "ReportService" + }, + "shortName": "GetReport" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.GetReportRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.Report", + "shortName": "get_report" + }, + "description": "Sample for GetReport", + "file": "admanager_v1_generated_report_service_get_report_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_ReportService_GetReport_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_report_service_get_report_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.ReportServiceClient", + "shortName": "ReportServiceClient" + }, + "fullName": "google.ads.admanager_v1.ReportServiceClient.list_reports", + "method": { + "fullName": "google.ads.admanager.v1.ReportService.ListReports", + "service": { + "fullName": "google.ads.admanager.v1.ReportService", + "shortName": "ReportService" + }, + "shortName": "ListReports" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.ListReportsRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.services.report_service.pagers.ListReportsPager", + "shortName": "list_reports" + }, + "description": "Sample for ListReports", + "file": "admanager_v1_generated_report_service_list_reports_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_ReportService_ListReports_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_report_service_list_reports_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.ReportServiceClient", + "shortName": "ReportServiceClient" + }, + "fullName": "google.ads.admanager_v1.ReportServiceClient.run_report", + "method": { + "fullName": "google.ads.admanager.v1.ReportService.RunReport", + "service": { + "fullName": "google.ads.admanager.v1.ReportService", + "shortName": "ReportService" + }, + "shortName": "RunReport" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.RunReportRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "run_report" + }, + "description": "Sample for RunReport", + "file": "admanager_v1_generated_report_service_run_report_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_ReportService_RunReport_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_report_service_run_report_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.ReportServiceClient", + "shortName": "ReportServiceClient" + }, + "fullName": "google.ads.admanager_v1.ReportServiceClient.update_report", + "method": { + "fullName": "google.ads.admanager.v1.ReportService.UpdateReport", + "service": { + "fullName": "google.ads.admanager.v1.ReportService", + "shortName": "ReportService" + }, + "shortName": "UpdateReport" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.UpdateReportRequest" + }, + { + "name": "report", + "type": "google.ads.admanager_v1.types.Report" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.Report", + "shortName": "update_report" + }, + "description": "Sample for UpdateReport", + "file": "admanager_v1_generated_report_service_update_report_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_ReportService_UpdateReport_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_report_service_update_report_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.RoleServiceClient", + "shortName": "RoleServiceClient" + }, + "fullName": "google.ads.admanager_v1.RoleServiceClient.get_role", + "method": { + "fullName": "google.ads.admanager.v1.RoleService.GetRole", + "service": { + "fullName": "google.ads.admanager.v1.RoleService", + "shortName": "RoleService" + }, + "shortName": "GetRole" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.GetRoleRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.Role", + "shortName": "get_role" + }, + "description": "Sample for GetRole", + "file": "admanager_v1_generated_role_service_get_role_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_RoleService_GetRole_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_role_service_get_role_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.RoleServiceClient", + "shortName": "RoleServiceClient" + }, + "fullName": "google.ads.admanager_v1.RoleServiceClient.list_roles", + "method": { + "fullName": "google.ads.admanager.v1.RoleService.ListRoles", + "service": { + "fullName": "google.ads.admanager.v1.RoleService", + "shortName": "RoleService" + }, + "shortName": "ListRoles" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.ListRolesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.services.role_service.pagers.ListRolesPager", + "shortName": "list_roles" + }, + "description": "Sample for ListRoles", + "file": "admanager_v1_generated_role_service_list_roles_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_RoleService_ListRoles_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_role_service_list_roles_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.SiteServiceClient", + "shortName": "SiteServiceClient" + }, + "fullName": "google.ads.admanager_v1.SiteServiceClient.batch_create_sites", + "method": { + "fullName": "google.ads.admanager.v1.SiteService.BatchCreateSites", + "service": { + "fullName": "google.ads.admanager.v1.SiteService", + "shortName": "SiteService" + }, + "shortName": "BatchCreateSites" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.BatchCreateSitesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "requests", + "type": "MutableSequence[google.ads.admanager_v1.types.CreateSiteRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.BatchCreateSitesResponse", + "shortName": "batch_create_sites" + }, + "description": "Sample for BatchCreateSites", + "file": "admanager_v1_generated_site_service_batch_create_sites_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_SiteService_BatchCreateSites_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_site_service_batch_create_sites_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.SiteServiceClient", + "shortName": "SiteServiceClient" + }, + "fullName": "google.ads.admanager_v1.SiteServiceClient.batch_deactivate_sites", + "method": { + "fullName": "google.ads.admanager.v1.SiteService.BatchDeactivateSites", + "service": { + "fullName": "google.ads.admanager.v1.SiteService", + "shortName": "SiteService" + }, + "shortName": "BatchDeactivateSites" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.BatchDeactivateSitesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "names", + "type": "MutableSequence[str]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.BatchDeactivateSitesResponse", + "shortName": "batch_deactivate_sites" + }, + "description": "Sample for BatchDeactivateSites", + "file": "admanager_v1_generated_site_service_batch_deactivate_sites_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_SiteService_BatchDeactivateSites_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_site_service_batch_deactivate_sites_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.SiteServiceClient", + "shortName": "SiteServiceClient" + }, + "fullName": "google.ads.admanager_v1.SiteServiceClient.batch_submit_sites_for_approval", + "method": { + "fullName": "google.ads.admanager.v1.SiteService.BatchSubmitSitesForApproval", + "service": { + "fullName": "google.ads.admanager.v1.SiteService", + "shortName": "SiteService" + }, + "shortName": "BatchSubmitSitesForApproval" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.BatchSubmitSitesForApprovalRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "names", + "type": "MutableSequence[str]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.BatchSubmitSitesForApprovalResponse", + "shortName": "batch_submit_sites_for_approval" + }, + "description": "Sample for BatchSubmitSitesForApproval", + "file": "admanager_v1_generated_site_service_batch_submit_sites_for_approval_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_SiteService_BatchSubmitSitesForApproval_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_site_service_batch_submit_sites_for_approval_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.SiteServiceClient", + "shortName": "SiteServiceClient" }, - "fullName": "google.ads.admanager_v1.PrivateAuctionServiceClient.list_private_auctions", + "fullName": "google.ads.admanager_v1.SiteServiceClient.batch_update_sites", "method": { - "fullName": "google.ads.admanager.v1.PrivateAuctionService.ListPrivateAuctions", + "fullName": "google.ads.admanager.v1.SiteService.BatchUpdateSites", "service": { - "fullName": "google.ads.admanager.v1.PrivateAuctionService", - "shortName": "PrivateAuctionService" + "fullName": "google.ads.admanager.v1.SiteService", + "shortName": "SiteService" }, - "shortName": "ListPrivateAuctions" + "shortName": "BatchUpdateSites" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.ListPrivateAuctionsRequest" + "type": "google.ads.admanager_v1.types.BatchUpdateSitesRequest" }, { "name": "parent", "type": "str" }, + { + "name": "requests", + "type": "MutableSequence[google.ads.admanager_v1.types.UpdateSiteRequest]" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -3598,22 +9054,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.services.private_auction_service.pagers.ListPrivateAuctionsPager", - "shortName": "list_private_auctions" + "resultType": "google.ads.admanager_v1.types.BatchUpdateSitesResponse", + "shortName": "batch_update_sites" }, - "description": "Sample for ListPrivateAuctions", - "file": "admanager_v1_generated_private_auction_service_list_private_auctions_sync.py", + "description": "Sample for BatchUpdateSites", + "file": "admanager_v1_generated_site_service_batch_update_sites_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_PrivateAuctionService_ListPrivateAuctions_sync", + "regionTag": "admanager_v1_generated_SiteService_BatchUpdateSites_sync", "segments": [ { - "end": 52, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 51, "start": 27, "type": "SHORT" }, @@ -3633,41 +9089,41 @@ "type": "REQUEST_EXECUTION" }, { - "end": 53, + "end": 52, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_private_auction_service_list_private_auctions_sync.py" + "title": "admanager_v1_generated_site_service_batch_update_sites_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.PrivateAuctionServiceClient", - "shortName": "PrivateAuctionServiceClient" + "fullName": "google.ads.admanager_v1.SiteServiceClient", + "shortName": "SiteServiceClient" }, - "fullName": "google.ads.admanager_v1.PrivateAuctionServiceClient.update_private_auction", + "fullName": "google.ads.admanager_v1.SiteServiceClient.create_site", "method": { - "fullName": "google.ads.admanager.v1.PrivateAuctionService.UpdatePrivateAuction", + "fullName": "google.ads.admanager.v1.SiteService.CreateSite", "service": { - "fullName": "google.ads.admanager.v1.PrivateAuctionService", - "shortName": "PrivateAuctionService" + "fullName": "google.ads.admanager.v1.SiteService", + "shortName": "SiteService" }, - "shortName": "UpdatePrivateAuction" + "shortName": "CreateSite" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.UpdatePrivateAuctionRequest" + "type": "google.ads.admanager_v1.types.CreateSiteRequest" }, { - "name": "private_auction", - "type": "google.ads.admanager_v1.types.PrivateAuction" + "name": "parent", + "type": "str" }, { - "name": "update_mask", - "type": "google.protobuf.field_mask_pb2.FieldMask" + "name": "site", + "type": "google.ads.admanager_v1.types.Site" }, { "name": "retry", @@ -3682,22 +9138,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.PrivateAuction", - "shortName": "update_private_auction" + "resultType": "google.ads.admanager_v1.types.Site", + "shortName": "create_site" }, - "description": "Sample for UpdatePrivateAuction", - "file": "admanager_v1_generated_private_auction_service_update_private_auction_sync.py", + "description": "Sample for CreateSite", + "file": "admanager_v1_generated_site_service_create_site_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_PrivateAuctionService_UpdatePrivateAuction_sync", + "regionTag": "admanager_v1_generated_SiteService_CreateSite_sync", "segments": [ { - "end": 50, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 50, + "end": 51, "start": 27, "type": "SHORT" }, @@ -3707,43 +9163,43 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 44, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 47, - "start": 45, + "end": 48, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 51, - "start": 48, + "end": 52, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_private_auction_service_update_private_auction_sync.py" + "title": "admanager_v1_generated_site_service_create_site_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.ProgrammaticBuyerServiceClient", - "shortName": "ProgrammaticBuyerServiceClient" + "fullName": "google.ads.admanager_v1.SiteServiceClient", + "shortName": "SiteServiceClient" }, - "fullName": "google.ads.admanager_v1.ProgrammaticBuyerServiceClient.get_programmatic_buyer", + "fullName": "google.ads.admanager_v1.SiteServiceClient.get_site", "method": { - "fullName": "google.ads.admanager.v1.ProgrammaticBuyerService.GetProgrammaticBuyer", + "fullName": "google.ads.admanager.v1.SiteService.GetSite", "service": { - "fullName": "google.ads.admanager.v1.ProgrammaticBuyerService", - "shortName": "ProgrammaticBuyerService" + "fullName": "google.ads.admanager.v1.SiteService", + "shortName": "SiteService" }, - "shortName": "GetProgrammaticBuyer" + "shortName": "GetSite" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.GetProgrammaticBuyerRequest" + "type": "google.ads.admanager_v1.types.GetSiteRequest" }, { "name": "name", @@ -3762,14 +9218,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.ProgrammaticBuyer", - "shortName": "get_programmatic_buyer" + "resultType": "google.ads.admanager_v1.types.Site", + "shortName": "get_site" }, - "description": "Sample for GetProgrammaticBuyer", - "file": "admanager_v1_generated_programmatic_buyer_service_get_programmatic_buyer_sync.py", + "description": "Sample for GetSite", + "file": "admanager_v1_generated_site_service_get_site_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_ProgrammaticBuyerService_GetProgrammaticBuyer_sync", + "regionTag": "admanager_v1_generated_SiteService_GetSite_sync", "segments": [ { "end": 51, @@ -3802,28 +9258,28 @@ "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_programmatic_buyer_service_get_programmatic_buyer_sync.py" + "title": "admanager_v1_generated_site_service_get_site_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.ProgrammaticBuyerServiceClient", - "shortName": "ProgrammaticBuyerServiceClient" + "fullName": "google.ads.admanager_v1.SiteServiceClient", + "shortName": "SiteServiceClient" }, - "fullName": "google.ads.admanager_v1.ProgrammaticBuyerServiceClient.list_programmatic_buyers", + "fullName": "google.ads.admanager_v1.SiteServiceClient.list_sites", "method": { - "fullName": "google.ads.admanager.v1.ProgrammaticBuyerService.ListProgrammaticBuyers", + "fullName": "google.ads.admanager.v1.SiteService.ListSites", "service": { - "fullName": "google.ads.admanager.v1.ProgrammaticBuyerService", - "shortName": "ProgrammaticBuyerService" + "fullName": "google.ads.admanager.v1.SiteService", + "shortName": "SiteService" }, - "shortName": "ListProgrammaticBuyers" + "shortName": "ListSites" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.ListProgrammaticBuyersRequest" + "type": "google.ads.admanager_v1.types.ListSitesRequest" }, { "name": "parent", @@ -3842,14 +9298,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.services.programmatic_buyer_service.pagers.ListProgrammaticBuyersPager", - "shortName": "list_programmatic_buyers" + "resultType": "google.ads.admanager_v1.services.site_service.pagers.ListSitesPager", + "shortName": "list_sites" }, - "description": "Sample for ListProgrammaticBuyers", - "file": "admanager_v1_generated_programmatic_buyer_service_list_programmatic_buyers_sync.py", + "description": "Sample for ListSites", + "file": "admanager_v1_generated_site_service_list_sites_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_ProgrammaticBuyerService_ListProgrammaticBuyers_sync", + "regionTag": "admanager_v1_generated_SiteService_ListSites_sync", "segments": [ { "end": 52, @@ -3882,36 +9338,36 @@ "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_programmatic_buyer_service_list_programmatic_buyers_sync.py" + "title": "admanager_v1_generated_site_service_list_sites_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.ReportServiceClient", - "shortName": "ReportServiceClient" + "fullName": "google.ads.admanager_v1.SiteServiceClient", + "shortName": "SiteServiceClient" }, - "fullName": "google.ads.admanager_v1.ReportServiceClient.create_report", + "fullName": "google.ads.admanager_v1.SiteServiceClient.update_site", "method": { - "fullName": "google.ads.admanager.v1.ReportService.CreateReport", + "fullName": "google.ads.admanager.v1.SiteService.UpdateSite", "service": { - "fullName": "google.ads.admanager.v1.ReportService", - "shortName": "ReportService" + "fullName": "google.ads.admanager.v1.SiteService", + "shortName": "SiteService" }, - "shortName": "CreateReport" + "shortName": "UpdateSite" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.CreateReportRequest" + "type": "google.ads.admanager_v1.types.UpdateSiteRequest" }, { - "name": "parent", - "type": "str" + "name": "site", + "type": "google.ads.admanager_v1.types.Site" }, { - "name": "report", - "type": "google.ads.admanager_v1.types.Report" + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" }, { "name": "retry", @@ -3926,22 +9382,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.Report", - "shortName": "create_report" + "resultType": "google.ads.admanager_v1.types.Site", + "shortName": "update_site" }, - "description": "Sample for CreateReport", - "file": "admanager_v1_generated_report_service_create_report_sync.py", + "description": "Sample for UpdateSite", + "file": "admanager_v1_generated_site_service_update_site_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_ReportService_CreateReport_sync", + "regionTag": "admanager_v1_generated_SiteService_UpdateSite_sync", "segments": [ { - "end": 57, + "end": 50, "start": 27, "type": "FULL" }, { - "end": 57, + "end": 50, "start": 27, "type": "SHORT" }, @@ -3950,47 +9406,127 @@ "start": 38, "type": "CLIENT_INITIALIZATION" }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "admanager_v1_generated_site_service_update_site_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.ads.admanager_v1.TaxonomyCategoryServiceClient", + "shortName": "TaxonomyCategoryServiceClient" + }, + "fullName": "google.ads.admanager_v1.TaxonomyCategoryServiceClient.get_taxonomy_category", + "method": { + "fullName": "google.ads.admanager.v1.TaxonomyCategoryService.GetTaxonomyCategory", + "service": { + "fullName": "google.ads.admanager.v1.TaxonomyCategoryService", + "shortName": "TaxonomyCategoryService" + }, + "shortName": "GetTaxonomyCategory" + }, + "parameters": [ + { + "name": "request", + "type": "google.ads.admanager_v1.types.GetTaxonomyCategoryRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.ads.admanager_v1.types.TaxonomyCategory", + "shortName": "get_taxonomy_category" + }, + "description": "Sample for GetTaxonomyCategory", + "file": "admanager_v1_generated_taxonomy_category_service_get_taxonomy_category_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "admanager_v1_generated_TaxonomyCategoryService_GetTaxonomyCategory_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, { "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 54, - "start": 52, + "end": 48, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 58, - "start": 55, + "end": 52, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_report_service_create_report_sync.py" + "title": "admanager_v1_generated_taxonomy_category_service_get_taxonomy_category_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.ReportServiceClient", - "shortName": "ReportServiceClient" + "fullName": "google.ads.admanager_v1.TaxonomyCategoryServiceClient", + "shortName": "TaxonomyCategoryServiceClient" }, - "fullName": "google.ads.admanager_v1.ReportServiceClient.fetch_report_result_rows", + "fullName": "google.ads.admanager_v1.TaxonomyCategoryServiceClient.list_taxonomy_categories", "method": { - "fullName": "google.ads.admanager.v1.ReportService.FetchReportResultRows", + "fullName": "google.ads.admanager.v1.TaxonomyCategoryService.ListTaxonomyCategories", "service": { - "fullName": "google.ads.admanager.v1.ReportService", - "shortName": "ReportService" + "fullName": "google.ads.admanager.v1.TaxonomyCategoryService", + "shortName": "TaxonomyCategoryService" }, - "shortName": "FetchReportResultRows" + "shortName": "ListTaxonomyCategories" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.FetchReportResultRowsRequest" + "type": "google.ads.admanager_v1.types.ListTaxonomyCategoriesRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -4006,22 +9542,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.services.report_service.pagers.FetchReportResultRowsPager", - "shortName": "fetch_report_result_rows" + "resultType": "google.ads.admanager_v1.services.taxonomy_category_service.pagers.ListTaxonomyCategoriesPager", + "shortName": "list_taxonomy_categories" }, - "description": "Sample for FetchReportResultRows", - "file": "admanager_v1_generated_report_service_fetch_report_result_rows_sync.py", + "description": "Sample for ListTaxonomyCategories", + "file": "admanager_v1_generated_taxonomy_category_service_list_taxonomy_categories_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_ReportService_FetchReportResultRows_sync", + "regionTag": "admanager_v1_generated_TaxonomyCategoryService_ListTaxonomyCategories_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -4031,48 +9567,52 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 44, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 47, - "start": 45, + "end": 48, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 52, - "start": 48, + "end": 53, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_report_service_fetch_report_result_rows_sync.py" + "title": "admanager_v1_generated_taxonomy_category_service_list_taxonomy_categories_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.ReportServiceClient", - "shortName": "ReportServiceClient" + "fullName": "google.ads.admanager_v1.TeamServiceClient", + "shortName": "TeamServiceClient" }, - "fullName": "google.ads.admanager_v1.ReportServiceClient.get_report", + "fullName": "google.ads.admanager_v1.TeamServiceClient.batch_activate_teams", "method": { - "fullName": "google.ads.admanager.v1.ReportService.GetReport", + "fullName": "google.ads.admanager.v1.TeamService.BatchActivateTeams", "service": { - "fullName": "google.ads.admanager.v1.ReportService", - "shortName": "ReportService" + "fullName": "google.ads.admanager.v1.TeamService", + "shortName": "TeamService" }, - "shortName": "GetReport" + "shortName": "BatchActivateTeams" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.GetReportRequest" + "type": "google.ads.admanager_v1.types.BatchActivateTeamsRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, + { + "name": "names", + "type": "MutableSequence[str]" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -4086,22 +9626,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.Report", - "shortName": "get_report" + "resultType": "google.ads.admanager_v1.types.BatchActivateTeamsResponse", + "shortName": "batch_activate_teams" }, - "description": "Sample for GetReport", - "file": "admanager_v1_generated_report_service_get_report_sync.py", + "description": "Sample for BatchActivateTeams", + "file": "admanager_v1_generated_team_service_batch_activate_teams_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_ReportService_GetReport_sync", + "regionTag": "admanager_v1_generated_TeamService_BatchActivateTeams_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -4111,48 +9651,52 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 46, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 49, + "start": 47, "type": "REQUEST_EXECUTION" }, { - "end": 52, - "start": 49, + "end": 53, + "start": 50, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_report_service_get_report_sync.py" + "title": "admanager_v1_generated_team_service_batch_activate_teams_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.ReportServiceClient", - "shortName": "ReportServiceClient" + "fullName": "google.ads.admanager_v1.TeamServiceClient", + "shortName": "TeamServiceClient" }, - "fullName": "google.ads.admanager_v1.ReportServiceClient.list_reports", + "fullName": "google.ads.admanager_v1.TeamServiceClient.batch_create_teams", "method": { - "fullName": "google.ads.admanager.v1.ReportService.ListReports", + "fullName": "google.ads.admanager.v1.TeamService.BatchCreateTeams", "service": { - "fullName": "google.ads.admanager.v1.ReportService", - "shortName": "ReportService" + "fullName": "google.ads.admanager.v1.TeamService", + "shortName": "TeamService" }, - "shortName": "ListReports" + "shortName": "BatchCreateTeams" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.ListReportsRequest" + "type": "google.ads.admanager_v1.types.BatchCreateTeamsRequest" }, { "name": "parent", "type": "str" }, + { + "name": "requests", + "type": "MutableSequence[google.ads.admanager_v1.types.CreateTeamRequest]" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -4166,22 +9710,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.services.report_service.pagers.ListReportsPager", - "shortName": "list_reports" + "resultType": "google.ads.admanager_v1.types.BatchCreateTeamsResponse", + "shortName": "batch_create_teams" }, - "description": "Sample for ListReports", - "file": "admanager_v1_generated_report_service_list_reports_sync.py", + "description": "Sample for BatchCreateTeams", + "file": "admanager_v1_generated_team_service_batch_create_teams_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_ReportService_ListReports_sync", + "regionTag": "admanager_v1_generated_TeamService_BatchCreateTeams_sync", "segments": [ { - "end": 52, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 55, "start": 27, "type": "SHORT" }, @@ -4191,48 +9735,52 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 49, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 52, + "start": 50, "type": "REQUEST_EXECUTION" }, { - "end": 53, - "start": 49, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_report_service_list_reports_sync.py" + "title": "admanager_v1_generated_team_service_batch_create_teams_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.ReportServiceClient", - "shortName": "ReportServiceClient" + "fullName": "google.ads.admanager_v1.TeamServiceClient", + "shortName": "TeamServiceClient" }, - "fullName": "google.ads.admanager_v1.ReportServiceClient.run_report", + "fullName": "google.ads.admanager_v1.TeamServiceClient.batch_deactivate_teams", "method": { - "fullName": "google.ads.admanager.v1.ReportService.RunReport", + "fullName": "google.ads.admanager.v1.TeamService.BatchDeactivateTeams", "service": { - "fullName": "google.ads.admanager.v1.ReportService", - "shortName": "ReportService" + "fullName": "google.ads.admanager.v1.TeamService", + "shortName": "TeamService" }, - "shortName": "RunReport" + "shortName": "BatchDeactivateTeams" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.RunReportRequest" + "type": "google.ads.admanager_v1.types.BatchDeactivateTeamsRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, + { + "name": "names", + "type": "MutableSequence[str]" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -4246,22 +9794,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.api_core.operation.Operation", - "shortName": "run_report" + "resultType": "google.ads.admanager_v1.types.BatchDeactivateTeamsResponse", + "shortName": "batch_deactivate_teams" }, - "description": "Sample for RunReport", - "file": "admanager_v1_generated_report_service_run_report_sync.py", + "description": "Sample for BatchDeactivateTeams", + "file": "admanager_v1_generated_team_service_batch_deactivate_teams_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_ReportService_RunReport_sync", + "regionTag": "admanager_v1_generated_TeamService_BatchDeactivateTeams_sync", "segments": [ { - "end": 55, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 55, + "end": 52, "start": 27, "type": "SHORT" }, @@ -4271,51 +9819,51 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 46, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 52, - "start": 46, + "end": 49, + "start": 47, "type": "REQUEST_EXECUTION" }, { - "end": 56, - "start": 53, + "end": 53, + "start": 50, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_report_service_run_report_sync.py" + "title": "admanager_v1_generated_team_service_batch_deactivate_teams_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.ReportServiceClient", - "shortName": "ReportServiceClient" + "fullName": "google.ads.admanager_v1.TeamServiceClient", + "shortName": "TeamServiceClient" }, - "fullName": "google.ads.admanager_v1.ReportServiceClient.update_report", + "fullName": "google.ads.admanager_v1.TeamServiceClient.batch_update_teams", "method": { - "fullName": "google.ads.admanager.v1.ReportService.UpdateReport", + "fullName": "google.ads.admanager.v1.TeamService.BatchUpdateTeams", "service": { - "fullName": "google.ads.admanager.v1.ReportService", - "shortName": "ReportService" + "fullName": "google.ads.admanager.v1.TeamService", + "shortName": "TeamService" }, - "shortName": "UpdateReport" + "shortName": "BatchUpdateTeams" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.UpdateReportRequest" + "type": "google.ads.admanager_v1.types.BatchUpdateTeamsRequest" }, { - "name": "report", - "type": "google.ads.admanager_v1.types.Report" + "name": "parent", + "type": "str" }, { - "name": "update_mask", - "type": "google.protobuf.field_mask_pb2.FieldMask" + "name": "requests", + "type": "MutableSequence[google.ads.admanager_v1.types.UpdateTeamRequest]" }, { "name": "retry", @@ -4330,22 +9878,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.Report", - "shortName": "update_report" + "resultType": "google.ads.admanager_v1.types.BatchUpdateTeamsResponse", + "shortName": "batch_update_teams" }, - "description": "Sample for UpdateReport", - "file": "admanager_v1_generated_report_service_update_report_sync.py", + "description": "Sample for BatchUpdateTeams", + "file": "admanager_v1_generated_team_service_batch_update_teams_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_ReportService_UpdateReport_sync", + "regionTag": "admanager_v1_generated_TeamService_BatchUpdateTeams_sync", "segments": [ { - "end": 56, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 56, + "end": 51, "start": 27, "type": "SHORT" }, @@ -4355,48 +9903,52 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 50, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 53, - "start": 51, + "end": 48, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 57, - "start": 54, + "end": 52, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_report_service_update_report_sync.py" + "title": "admanager_v1_generated_team_service_batch_update_teams_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.RoleServiceClient", - "shortName": "RoleServiceClient" + "fullName": "google.ads.admanager_v1.TeamServiceClient", + "shortName": "TeamServiceClient" }, - "fullName": "google.ads.admanager_v1.RoleServiceClient.get_role", + "fullName": "google.ads.admanager_v1.TeamServiceClient.create_team", "method": { - "fullName": "google.ads.admanager.v1.RoleService.GetRole", + "fullName": "google.ads.admanager.v1.TeamService.CreateTeam", "service": { - "fullName": "google.ads.admanager.v1.RoleService", - "shortName": "RoleService" + "fullName": "google.ads.admanager.v1.TeamService", + "shortName": "TeamService" }, - "shortName": "GetRole" + "shortName": "CreateTeam" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.GetRoleRequest" + "type": "google.ads.admanager_v1.types.CreateTeamRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, + { + "name": "team", + "type": "google.ads.admanager_v1.types.Team" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -4410,14 +9962,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.Role", - "shortName": "get_role" + "resultType": "google.ads.admanager_v1.types.Team", + "shortName": "create_team" }, - "description": "Sample for GetRole", - "file": "admanager_v1_generated_role_service_get_role_sync.py", + "description": "Sample for CreateTeam", + "file": "admanager_v1_generated_team_service_create_team_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_RoleService_GetRole_sync", + "regionTag": "admanager_v1_generated_TeamService_CreateTeam_sync", "segments": [ { "end": 51, @@ -4450,31 +10002,31 @@ "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_role_service_get_role_sync.py" + "title": "admanager_v1_generated_team_service_create_team_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.RoleServiceClient", - "shortName": "RoleServiceClient" + "fullName": "google.ads.admanager_v1.TeamServiceClient", + "shortName": "TeamServiceClient" }, - "fullName": "google.ads.admanager_v1.RoleServiceClient.list_roles", + "fullName": "google.ads.admanager_v1.TeamServiceClient.get_team", "method": { - "fullName": "google.ads.admanager.v1.RoleService.ListRoles", + "fullName": "google.ads.admanager.v1.TeamService.GetTeam", "service": { - "fullName": "google.ads.admanager.v1.RoleService", - "shortName": "RoleService" + "fullName": "google.ads.admanager.v1.TeamService", + "shortName": "TeamService" }, - "shortName": "ListRoles" + "shortName": "GetTeam" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.ListRolesRequest" + "type": "google.ads.admanager_v1.types.GetTeamRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, { @@ -4490,22 +10042,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.services.role_service.pagers.ListRolesPager", - "shortName": "list_roles" + "resultType": "google.ads.admanager_v1.types.Team", + "shortName": "get_team" }, - "description": "Sample for ListRoles", - "file": "admanager_v1_generated_role_service_list_roles_sync.py", + "description": "Sample for GetTeam", + "file": "admanager_v1_generated_team_service_get_team_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_RoleService_ListRoles_sync", + "regionTag": "admanager_v1_generated_TeamService_GetTeam_sync", "segments": [ { - "end": 52, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 51, "start": 27, "type": "SHORT" }, @@ -4525,36 +10077,36 @@ "type": "REQUEST_EXECUTION" }, { - "end": 53, + "end": 52, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_role_service_list_roles_sync.py" + "title": "admanager_v1_generated_team_service_get_team_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.TaxonomyCategoryServiceClient", - "shortName": "TaxonomyCategoryServiceClient" + "fullName": "google.ads.admanager_v1.TeamServiceClient", + "shortName": "TeamServiceClient" }, - "fullName": "google.ads.admanager_v1.TaxonomyCategoryServiceClient.get_taxonomy_category", + "fullName": "google.ads.admanager_v1.TeamServiceClient.list_teams", "method": { - "fullName": "google.ads.admanager.v1.TaxonomyCategoryService.GetTaxonomyCategory", + "fullName": "google.ads.admanager.v1.TeamService.ListTeams", "service": { - "fullName": "google.ads.admanager.v1.TaxonomyCategoryService", - "shortName": "TaxonomyCategoryService" + "fullName": "google.ads.admanager.v1.TeamService", + "shortName": "TeamService" }, - "shortName": "GetTaxonomyCategory" + "shortName": "ListTeams" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.GetTaxonomyCategoryRequest" + "type": "google.ads.admanager_v1.types.ListTeamsRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -4570,22 +10122,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.types.TaxonomyCategory", - "shortName": "get_taxonomy_category" + "resultType": "google.ads.admanager_v1.services.team_service.pagers.ListTeamsPager", + "shortName": "list_teams" }, - "description": "Sample for GetTaxonomyCategory", - "file": "admanager_v1_generated_taxonomy_category_service_get_taxonomy_category_sync.py", + "description": "Sample for ListTeams", + "file": "admanager_v1_generated_team_service_list_teams_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_TaxonomyCategoryService_GetTaxonomyCategory_sync", + "regionTag": "admanager_v1_generated_TeamService_ListTeams_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -4605,37 +10157,41 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_taxonomy_category_service_get_taxonomy_category_sync.py" + "title": "admanager_v1_generated_team_service_list_teams_sync.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.ads.admanager_v1.TaxonomyCategoryServiceClient", - "shortName": "TaxonomyCategoryServiceClient" + "fullName": "google.ads.admanager_v1.TeamServiceClient", + "shortName": "TeamServiceClient" }, - "fullName": "google.ads.admanager_v1.TaxonomyCategoryServiceClient.list_taxonomy_categories", + "fullName": "google.ads.admanager_v1.TeamServiceClient.update_team", "method": { - "fullName": "google.ads.admanager.v1.TaxonomyCategoryService.ListTaxonomyCategories", + "fullName": "google.ads.admanager.v1.TeamService.UpdateTeam", "service": { - "fullName": "google.ads.admanager.v1.TaxonomyCategoryService", - "shortName": "TaxonomyCategoryService" + "fullName": "google.ads.admanager.v1.TeamService", + "shortName": "TeamService" }, - "shortName": "ListTaxonomyCategories" + "shortName": "UpdateTeam" }, "parameters": [ { "name": "request", - "type": "google.ads.admanager_v1.types.ListTaxonomyCategoriesRequest" + "type": "google.ads.admanager_v1.types.UpdateTeamRequest" }, { - "name": "parent", - "type": "str" + "name": "team", + "type": "google.ads.admanager_v1.types.Team" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" }, { "name": "retry", @@ -4650,22 +10206,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.ads.admanager_v1.services.taxonomy_category_service.pagers.ListTaxonomyCategoriesPager", - "shortName": "list_taxonomy_categories" + "resultType": "google.ads.admanager_v1.types.Team", + "shortName": "update_team" }, - "description": "Sample for ListTaxonomyCategories", - "file": "admanager_v1_generated_taxonomy_category_service_list_taxonomy_categories_sync.py", + "description": "Sample for UpdateTeam", + "file": "admanager_v1_generated_team_service_update_team_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "admanager_v1_generated_TaxonomyCategoryService_ListTaxonomyCategories_sync", + "regionTag": "admanager_v1_generated_TeamService_UpdateTeam_sync", "segments": [ { - "end": 52, + "end": 50, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 50, "start": 27, "type": "SHORT" }, @@ -4675,22 +10231,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 44, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 47, + "start": 45, "type": "REQUEST_EXECUTION" }, { - "end": 53, - "start": 49, + "end": 51, + "start": 48, "type": "RESPONSE_HANDLING" } ], - "title": "admanager_v1_generated_taxonomy_category_service_list_taxonomy_categories_sync.py" + "title": "admanager_v1_generated_team_service_update_team_sync.py" }, { "canonical": true, diff --git a/packages/google-ads-admanager/scripts/fixup_admanager_v1_keywords.py b/packages/google-ads-admanager/scripts/fixup_admanager_v1_keywords.py index b286c0725697..b3c3a577a6d1 100644 --- a/packages/google-ads-admanager/scripts/fixup_admanager_v1_keywords.py +++ b/packages/google-ads-admanager/scripts/fixup_admanager_v1_keywords.py @@ -39,25 +39,67 @@ def partition( class admanagerCallTransformer(cst.CSTTransformer): CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + 'batch_activate_custom_fields': ('parent', 'names', ), + 'batch_activate_placements': ('parent', 'names', ), + 'batch_activate_teams': ('parent', 'names', ), + 'batch_allow_ad_review_center_ads': ('parent', 'names', ), + 'batch_archive_placements': ('parent', 'names', ), + 'batch_block_ad_review_center_ads': ('parent', 'names', ), + 'batch_create_contacts': ('parent', 'requests', ), + 'batch_create_custom_fields': ('parent', 'requests', ), 'batch_create_entity_signals_mappings': ('parent', 'requests', ), + 'batch_create_placements': ('parent', 'requests', ), + 'batch_create_sites': ('parent', 'requests', ), + 'batch_create_teams': ('parent', 'requests', ), + 'batch_deactivate_custom_fields': ('parent', 'names', ), + 'batch_deactivate_placements': ('parent', 'names', ), + 'batch_deactivate_sites': ('parent', 'names', ), + 'batch_deactivate_teams': ('parent', 'names', ), + 'batch_submit_sites_for_approval': ('parent', 'names', ), + 'batch_update_contacts': ('parent', 'requests', ), + 'batch_update_custom_fields': ('parent', 'requests', ), 'batch_update_entity_signals_mappings': ('parent', 'requests', ), + 'batch_update_placements': ('parent', 'requests', ), + 'batch_update_sites': ('parent', 'requests', ), + 'batch_update_teams': ('parent', 'requests', ), 'create_ad_break': ('parent', 'ad_break', ), + 'create_contact': ('parent', 'contact', ), + 'create_custom_field': ('parent', 'custom_field', ), 'create_entity_signals_mapping': ('parent', 'entity_signals_mapping', ), + 'create_placement': ('parent', 'placement', ), 'create_private_auction': ('parent', 'private_auction', ), 'create_private_auction_deal': ('parent', 'private_auction_deal', ), 'create_report': ('parent', 'report', ), + 'create_site': ('parent', 'site', ), + 'create_team': ('parent', 'team', ), 'delete_ad_break': ('name', ), 'fetch_report_result_rows': ('name', 'page_size', 'page_token', ), 'get_ad_break': ('name', ), 'get_ad_unit': ('name', ), + 'get_application': ('name', ), + 'get_audience_segment': ('name', ), 'get_bandwidth_group': ('name', ), + 'get_browser': ('name', ), + 'get_browser_language': ('name', ), + 'get_cms_metadata_key': ('name', ), + 'get_cms_metadata_value': ('name', ), 'get_company': ('name', ), + 'get_contact': ('name', ), + 'get_content': ('name', ), + 'get_content_bundle': ('name', ), + 'get_content_label': ('name', ), + 'get_creative_template': ('name', ), 'get_custom_field': ('name', ), 'get_custom_targeting_key': ('name', ), 'get_custom_targeting_value': ('name', ), + 'get_device_capability': ('name', ), 'get_device_category': ('name', ), + 'get_device_manufacturer': ('name', ), 'get_entity_signals_mapping': ('name', ), 'get_geo_target': ('name', ), + 'get_mobile_carrier': ('name', ), + 'get_mobile_device': ('name', ), + 'get_mobile_device_submodel': ('name', ), 'get_network': ('name', ), 'get_operating_system': ('name', ), 'get_operating_system_version': ('name', ), @@ -68,19 +110,37 @@ class admanagerCallTransformer(cst.CSTTransformer): 'get_programmatic_buyer': ('name', ), 'get_report': ('name', ), 'get_role': ('name', ), + 'get_site': ('name', ), 'get_taxonomy_category': ('name', ), + 'get_team': ('name', ), 'get_user': ('name', ), 'list_ad_breaks': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), 'list_ad_units': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), 'list_ad_unit_sizes': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), + 'list_applications': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), + 'list_audience_segments': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), 'list_bandwidth_groups': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), + 'list_browser_languages': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), + 'list_browsers': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), + 'list_cms_metadata_keys': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), + 'list_cms_metadata_values': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), 'list_companies': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), + 'list_contacts': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), + 'list_content': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), + 'list_content_bundles': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), + 'list_content_labels': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), + 'list_creative_templates': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), 'list_custom_fields': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), 'list_custom_targeting_keys': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), 'list_custom_targeting_values': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), + 'list_device_capabilities': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), 'list_device_categories': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), + 'list_device_manufacturers': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), 'list_entity_signals_mappings': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), 'list_geo_targets': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), + 'list_mobile_carriers': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), + 'list_mobile_devices': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), + 'list_mobile_device_submodels': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), 'list_networks': (), 'list_operating_systems': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), 'list_operating_system_versions': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), @@ -91,13 +151,21 @@ class admanagerCallTransformer(cst.CSTTransformer): 'list_programmatic_buyers': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), 'list_reports': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), 'list_roles': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), + 'list_sites': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), 'list_taxonomy_categories': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), + 'list_teams': ('parent', 'page_size', 'page_token', 'filter', 'order_by', 'skip', ), 'run_report': ('name', ), + 'search_ad_review_center_ads': ('parent', 'status', 'page_size', 'page_token', 'ad_review_center_ad_id', 'date_time_range', 'search_text', 'buyer_account_id', ), 'update_ad_break': ('ad_break', 'update_mask', ), + 'update_contact': ('contact', 'update_mask', ), + 'update_custom_field': ('custom_field', 'update_mask', ), 'update_entity_signals_mapping': ('entity_signals_mapping', 'update_mask', ), + 'update_placement': ('placement', 'update_mask', ), 'update_private_auction': ('private_auction', 'update_mask', ), 'update_private_auction_deal': ('private_auction_deal', 'update_mask', ), 'update_report': ('report', 'update_mask', ), + 'update_site': ('site', 'update_mask', ), + 'update_team': ('team', 'update_mask', ), } def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode: diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_ad_review_center_ad_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_ad_review_center_ad_service.py new file mode 100644 index 000000000000..7056473614f8 --- /dev/null +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_ad_review_center_ad_service.py @@ -0,0 +1,2727 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import ( + future, + gapic_v1, + grpc_helpers, + grpc_helpers_async, + operation, + operations_v1, + path_template, +) +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import operation_async # type: ignore +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import timestamp_pb2 # type: ignore +from google.type import interval_pb2 # type: ignore + +from google.ads.admanager_v1.services.ad_review_center_ad_service import ( + AdReviewCenterAdServiceClient, + pagers, + transports, +) +from google.ads.admanager_v1.types import ( + ad_review_center_ad_enums, + ad_review_center_ad_messages, + ad_review_center_ad_service, +) + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert AdReviewCenterAdServiceClient._get_default_mtls_endpoint(None) is None + assert ( + AdReviewCenterAdServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + AdReviewCenterAdServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + AdReviewCenterAdServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + AdReviewCenterAdServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + AdReviewCenterAdServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +def test__read_environment_variables(): + assert AdReviewCenterAdServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert AdReviewCenterAdServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert AdReviewCenterAdServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + AdReviewCenterAdServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert AdReviewCenterAdServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert AdReviewCenterAdServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert AdReviewCenterAdServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + AdReviewCenterAdServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert AdReviewCenterAdServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert AdReviewCenterAdServiceClient._get_client_cert_source(None, False) is None + assert ( + AdReviewCenterAdServiceClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + AdReviewCenterAdServiceClient._get_client_cert_source( + mock_provided_cert_source, True + ) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + AdReviewCenterAdServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + AdReviewCenterAdServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + AdReviewCenterAdServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AdReviewCenterAdServiceClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = AdReviewCenterAdServiceClient._DEFAULT_UNIVERSE + default_endpoint = AdReviewCenterAdServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = AdReviewCenterAdServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + AdReviewCenterAdServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + AdReviewCenterAdServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == AdReviewCenterAdServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + AdReviewCenterAdServiceClient._get_api_endpoint( + None, None, default_universe, "auto" + ) + == default_endpoint + ) + assert ( + AdReviewCenterAdServiceClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == AdReviewCenterAdServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + AdReviewCenterAdServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == AdReviewCenterAdServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + AdReviewCenterAdServiceClient._get_api_endpoint( + None, None, mock_universe, "never" + ) + == mock_endpoint + ) + assert ( + AdReviewCenterAdServiceClient._get_api_endpoint( + None, None, default_universe, "never" + ) + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + AdReviewCenterAdServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + AdReviewCenterAdServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + AdReviewCenterAdServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + AdReviewCenterAdServiceClient._get_universe_domain(None, None) + == AdReviewCenterAdServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + AdReviewCenterAdServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = AdReviewCenterAdServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = AdReviewCenterAdServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (AdReviewCenterAdServiceClient, "rest"), + ], +) +def test_ad_review_center_ad_service_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.AdReviewCenterAdServiceRestTransport, "rest"), + ], +) +def test_ad_review_center_ad_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (AdReviewCenterAdServiceClient, "rest"), + ], +) +def test_ad_review_center_ad_service_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +def test_ad_review_center_ad_service_client_get_transport_class(): + transport = AdReviewCenterAdServiceClient.get_transport_class() + available_transports = [ + transports.AdReviewCenterAdServiceRestTransport, + ] + assert transport in available_transports + + transport = AdReviewCenterAdServiceClient.get_transport_class("rest") + assert transport == transports.AdReviewCenterAdServiceRestTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + AdReviewCenterAdServiceClient, + transports.AdReviewCenterAdServiceRestTransport, + "rest", + ), + ], +) +@mock.patch.object( + AdReviewCenterAdServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AdReviewCenterAdServiceClient), +) +def test_ad_review_center_ad_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(AdReviewCenterAdServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(AdReviewCenterAdServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + AdReviewCenterAdServiceClient, + transports.AdReviewCenterAdServiceRestTransport, + "rest", + "true", + ), + ( + AdReviewCenterAdServiceClient, + transports.AdReviewCenterAdServiceRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + AdReviewCenterAdServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AdReviewCenterAdServiceClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_ad_review_center_ad_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [AdReviewCenterAdServiceClient]) +@mock.patch.object( + AdReviewCenterAdServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(AdReviewCenterAdServiceClient), +) +def test_ad_review_center_ad_service_client_get_mtls_endpoint_and_cert_source( + client_class, +): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize("client_class", [AdReviewCenterAdServiceClient]) +@mock.patch.object( + AdReviewCenterAdServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AdReviewCenterAdServiceClient), +) +def test_ad_review_center_ad_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = AdReviewCenterAdServiceClient._DEFAULT_UNIVERSE + default_endpoint = AdReviewCenterAdServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = AdReviewCenterAdServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + AdReviewCenterAdServiceClient, + transports.AdReviewCenterAdServiceRestTransport, + "rest", + ), + ], +) +def test_ad_review_center_ad_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + AdReviewCenterAdServiceClient, + transports.AdReviewCenterAdServiceRestTransport, + "rest", + None, + ), + ], +) +def test_ad_review_center_ad_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_search_ad_review_center_ads_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.search_ad_review_center_ads + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.search_ad_review_center_ads + ] = mock_rpc + + request = {} + client.search_ad_review_center_ads(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.search_ad_review_center_ads(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_search_ad_review_center_ads_rest_required_fields( + request_type=ad_review_center_ad_service.SearchAdReviewCenterAdsRequest, +): + transport_class = transports.AdReviewCenterAdServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).search_ad_review_center_ads._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).search_ad_review_center_ads._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "ad_review_center_ad_id", + "buyer_account_id", + "date_time_range", + "page_size", + "page_token", + "search_text", + "status", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = ad_review_center_ad_service.SearchAdReviewCenterAdsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = ( + ad_review_center_ad_service.SearchAdReviewCenterAdsResponse.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.search_ad_review_center_ads(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_search_ad_review_center_ads_rest_unset_required_fields(): + transport = transports.AdReviewCenterAdServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.search_ad_review_center_ads._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "adReviewCenterAdId", + "buyerAccountId", + "dateTimeRange", + "pageSize", + "pageToken", + "searchText", + "status", + ) + ) + & set( + ( + "parent", + "status", + ) + ) + ) + + +def test_search_ad_review_center_ads_rest_flattened(): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = ad_review_center_ad_service.SearchAdReviewCenterAdsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1/webProperties/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = ad_review_center_ad_service.SearchAdReviewCenterAdsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.search_ad_review_center_ads(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*/webProperties/*}/adReviewCenterAds:search" + % client.transport._host, + args[1], + ) + + +def test_search_ad_review_center_ads_rest_flattened_error(transport: str = "rest"): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.search_ad_review_center_ads( + ad_review_center_ad_service.SearchAdReviewCenterAdsRequest(), + parent="parent_value", + ) + + +def test_search_ad_review_center_ads_rest_pager(transport: str = "rest"): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + ad_review_center_ad_service.SearchAdReviewCenterAdsResponse( + ad_review_center_ads=[ + ad_review_center_ad_messages.AdReviewCenterAd(), + ad_review_center_ad_messages.AdReviewCenterAd(), + ad_review_center_ad_messages.AdReviewCenterAd(), + ], + next_page_token="abc", + ), + ad_review_center_ad_service.SearchAdReviewCenterAdsResponse( + ad_review_center_ads=[], + next_page_token="def", + ), + ad_review_center_ad_service.SearchAdReviewCenterAdsResponse( + ad_review_center_ads=[ + ad_review_center_ad_messages.AdReviewCenterAd(), + ], + next_page_token="ghi", + ), + ad_review_center_ad_service.SearchAdReviewCenterAdsResponse( + ad_review_center_ads=[ + ad_review_center_ad_messages.AdReviewCenterAd(), + ad_review_center_ad_messages.AdReviewCenterAd(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + ad_review_center_ad_service.SearchAdReviewCenterAdsResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "networks/sample1/webProperties/sample2"} + + pager = client.search_ad_review_center_ads(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, ad_review_center_ad_messages.AdReviewCenterAd) + for i in results + ) + + pages = list(client.search_ad_review_center_ads(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_batch_allow_ad_review_center_ads_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_allow_ad_review_center_ads + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_allow_ad_review_center_ads + ] = mock_rpc + + request = {} + client.batch_allow_ad_review_center_ads(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.batch_allow_ad_review_center_ads(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_allow_ad_review_center_ads_rest_required_fields( + request_type=ad_review_center_ad_service.BatchAllowAdReviewCenterAdsRequest, +): + transport_class = transports.AdReviewCenterAdServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["names"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_allow_ad_review_center_ads._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + jsonified_request["names"] = "names_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_allow_ad_review_center_ads._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "names" in jsonified_request + assert jsonified_request["names"] == "names_value" + + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_allow_ad_review_center_ads(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_allow_ad_review_center_ads_rest_unset_required_fields(): + transport = transports.AdReviewCenterAdServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.batch_allow_ad_review_center_ads._get_unset_required_fields({}) + ) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "names", + ) + ) + ) + + +def test_batch_allow_ad_review_center_ads_rest_flattened(): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1/webProperties/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.batch_allow_ad_review_center_ads(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*/webProperties/*}/adReviewCenterAds:batchAllow" + % client.transport._host, + args[1], + ) + + +def test_batch_allow_ad_review_center_ads_rest_flattened_error(transport: str = "rest"): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_allow_ad_review_center_ads( + ad_review_center_ad_service.BatchAllowAdReviewCenterAdsRequest(), + parent="parent_value", + ) + + +def test_batch_block_ad_review_center_ads_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_block_ad_review_center_ads + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_block_ad_review_center_ads + ] = mock_rpc + + request = {} + client.batch_block_ad_review_center_ads(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.batch_block_ad_review_center_ads(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_block_ad_review_center_ads_rest_required_fields( + request_type=ad_review_center_ad_service.BatchBlockAdReviewCenterAdsRequest, +): + transport_class = transports.AdReviewCenterAdServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["names"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_block_ad_review_center_ads._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + jsonified_request["names"] = "names_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_block_ad_review_center_ads._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "names" in jsonified_request + assert jsonified_request["names"] == "names_value" + + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_block_ad_review_center_ads(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_block_ad_review_center_ads_rest_unset_required_fields(): + transport = transports.AdReviewCenterAdServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = ( + transport.batch_block_ad_review_center_ads._get_unset_required_fields({}) + ) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "names", + ) + ) + ) + + +def test_batch_block_ad_review_center_ads_rest_flattened(): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1/webProperties/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.batch_block_ad_review_center_ads(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*/webProperties/*}/adReviewCenterAds:batchBlock" + % client.transport._host, + args[1], + ) + + +def test_batch_block_ad_review_center_ads_rest_flattened_error(transport: str = "rest"): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_block_ad_review_center_ads( + ad_review_center_ad_service.BatchBlockAdReviewCenterAdsRequest(), + parent="parent_value", + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.AdReviewCenterAdServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.AdReviewCenterAdServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AdReviewCenterAdServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.AdReviewCenterAdServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = AdReviewCenterAdServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = AdReviewCenterAdServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.AdReviewCenterAdServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AdReviewCenterAdServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.AdReviewCenterAdServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = AdReviewCenterAdServiceClient(transport=transport) + assert client.transport is transport + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.AdReviewCenterAdServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_rest(): + transport = AdReviewCenterAdServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_search_ad_review_center_ads_rest_bad_request( + request_type=ad_review_center_ad_service.SearchAdReviewCenterAdsRequest, +): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1/webProperties/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.search_ad_review_center_ads(request) + + +@pytest.mark.parametrize( + "request_type", + [ + ad_review_center_ad_service.SearchAdReviewCenterAdsRequest, + dict, + ], +) +def test_search_ad_review_center_ads_rest_call_success(request_type): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1/webProperties/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = ad_review_center_ad_service.SearchAdReviewCenterAdsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = ad_review_center_ad_service.SearchAdReviewCenterAdsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.search_ad_review_center_ads(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchAdReviewCenterAdsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_search_ad_review_center_ads_rest_interceptors(null_interceptor): + transport = transports.AdReviewCenterAdServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.AdReviewCenterAdServiceRestInterceptor(), + ) + client = AdReviewCenterAdServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.AdReviewCenterAdServiceRestInterceptor, + "post_search_ad_review_center_ads", + ) as post, mock.patch.object( + transports.AdReviewCenterAdServiceRestInterceptor, + "post_search_ad_review_center_ads_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.AdReviewCenterAdServiceRestInterceptor, + "pre_search_ad_review_center_ads", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = ad_review_center_ad_service.SearchAdReviewCenterAdsRequest.pb( + ad_review_center_ad_service.SearchAdReviewCenterAdsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = ( + ad_review_center_ad_service.SearchAdReviewCenterAdsResponse.to_json( + ad_review_center_ad_service.SearchAdReviewCenterAdsResponse() + ) + ) + req.return_value.content = return_value + + request = ad_review_center_ad_service.SearchAdReviewCenterAdsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = ( + ad_review_center_ad_service.SearchAdReviewCenterAdsResponse() + ) + post_with_metadata.return_value = ( + ad_review_center_ad_service.SearchAdReviewCenterAdsResponse(), + metadata, + ) + + client.search_ad_review_center_ads( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_batch_allow_ad_review_center_ads_rest_bad_request( + request_type=ad_review_center_ad_service.BatchAllowAdReviewCenterAdsRequest, +): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1/webProperties/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.batch_allow_ad_review_center_ads(request) + + +@pytest.mark.parametrize( + "request_type", + [ + ad_review_center_ad_service.BatchAllowAdReviewCenterAdsRequest, + dict, + ], +) +def test_batch_allow_ad_review_center_ads_rest_call_success(request_type): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1/webProperties/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.batch_allow_ad_review_center_ads(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_allow_ad_review_center_ads_rest_interceptors(null_interceptor): + transport = transports.AdReviewCenterAdServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.AdReviewCenterAdServiceRestInterceptor(), + ) + client = AdReviewCenterAdServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.AdReviewCenterAdServiceRestInterceptor, + "post_batch_allow_ad_review_center_ads", + ) as post, mock.patch.object( + transports.AdReviewCenterAdServiceRestInterceptor, + "post_batch_allow_ad_review_center_ads_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.AdReviewCenterAdServiceRestInterceptor, + "pre_batch_allow_ad_review_center_ads", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = ad_review_center_ad_service.BatchAllowAdReviewCenterAdsRequest.pb( + ad_review_center_ad_service.BatchAllowAdReviewCenterAdsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = ad_review_center_ad_service.BatchAllowAdReviewCenterAdsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.batch_allow_ad_review_center_ads( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_batch_block_ad_review_center_ads_rest_bad_request( + request_type=ad_review_center_ad_service.BatchBlockAdReviewCenterAdsRequest, +): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1/webProperties/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.batch_block_ad_review_center_ads(request) + + +@pytest.mark.parametrize( + "request_type", + [ + ad_review_center_ad_service.BatchBlockAdReviewCenterAdsRequest, + dict, + ], +) +def test_batch_block_ad_review_center_ads_rest_call_success(request_type): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1/webProperties/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.batch_block_ad_review_center_ads(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_block_ad_review_center_ads_rest_interceptors(null_interceptor): + transport = transports.AdReviewCenterAdServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.AdReviewCenterAdServiceRestInterceptor(), + ) + client = AdReviewCenterAdServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.AdReviewCenterAdServiceRestInterceptor, + "post_batch_block_ad_review_center_ads", + ) as post, mock.patch.object( + transports.AdReviewCenterAdServiceRestInterceptor, + "post_batch_block_ad_review_center_ads_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.AdReviewCenterAdServiceRestInterceptor, + "pre_batch_block_ad_review_center_ads", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = ad_review_center_ad_service.BatchBlockAdReviewCenterAdsRequest.pb( + ad_review_center_ad_service.BatchBlockAdReviewCenterAdsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = ad_review_center_ad_service.BatchBlockAdReviewCenterAdsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.batch_block_ad_review_center_ads( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "networks/sample1/operations/reports/runs/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "networks/sample1/operations/reports/runs/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_initialize_client_w_rest(): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_search_ad_review_center_ads_empty_call_rest(): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.search_ad_review_center_ads), "__call__" + ) as call: + client.search_ad_review_center_ads(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ad_review_center_ad_service.SearchAdReviewCenterAdsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_allow_ad_review_center_ads_empty_call_rest(): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_allow_ad_review_center_ads), "__call__" + ) as call: + client.batch_allow_ad_review_center_ads(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ad_review_center_ad_service.BatchAllowAdReviewCenterAdsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_block_ad_review_center_ads_empty_call_rest(): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_block_ad_review_center_ads), "__call__" + ) as call: + client.batch_block_ad_review_center_ads(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = ad_review_center_ad_service.BatchBlockAdReviewCenterAdsRequest() + + assert args[0] == request_msg + + +def test_ad_review_center_ad_service_rest_lro_client(): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + transport = client.transport + + # Ensure that we have an api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.AbstractOperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_ad_review_center_ad_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.AdReviewCenterAdServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_ad_review_center_ad_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.ads.admanager_v1.services.ad_review_center_ad_service.transports.AdReviewCenterAdServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.AdReviewCenterAdServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "search_ad_review_center_ads", + "batch_allow_ad_review_center_ads", + "batch_block_ad_review_center_ads", + "get_operation", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_ad_review_center_ad_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.ads.admanager_v1.services.ad_review_center_ad_service.transports.AdReviewCenterAdServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.AdReviewCenterAdServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id="octopus", + ) + + +def test_ad_review_center_ad_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.ads.admanager_v1.services.ad_review_center_ad_service.transports.AdReviewCenterAdServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.AdReviewCenterAdServiceTransport() + adc.assert_called_once() + + +def test_ad_review_center_ad_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + AdReviewCenterAdServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id=None, + ) + + +def test_ad_review_center_ad_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.AdReviewCenterAdServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_ad_review_center_ad_service_host_no_port(transport_name): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_ad_review_center_ad_service_host_with_port(transport_name): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_ad_review_center_ad_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = AdReviewCenterAdServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = AdReviewCenterAdServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.search_ad_review_center_ads._session + session2 = client2.transport.search_ad_review_center_ads._session + assert session1 != session2 + session1 = client1.transport.batch_allow_ad_review_center_ads._session + session2 = client2.transport.batch_allow_ad_review_center_ads._session + assert session1 != session2 + session1 = client1.transport.batch_block_ad_review_center_ads._session + session2 = client2.transport.batch_block_ad_review_center_ads._session + assert session1 != session2 + + +def test_ad_review_center_ad_path(): + network_code = "squid" + web_property_code = "clam" + ad_review_center_ad = "whelk" + expected = "networks/{network_code}/webProperties/{web_property_code}/adReviewCenterAds/{ad_review_center_ad}".format( + network_code=network_code, + web_property_code=web_property_code, + ad_review_center_ad=ad_review_center_ad, + ) + actual = AdReviewCenterAdServiceClient.ad_review_center_ad_path( + network_code, web_property_code, ad_review_center_ad + ) + assert expected == actual + + +def test_parse_ad_review_center_ad_path(): + expected = { + "network_code": "octopus", + "web_property_code": "oyster", + "ad_review_center_ad": "nudibranch", + } + path = AdReviewCenterAdServiceClient.ad_review_center_ad_path(**expected) + + # Check that the path construction is reversible. + actual = AdReviewCenterAdServiceClient.parse_ad_review_center_ad_path(path) + assert expected == actual + + +def test_web_property_path(): + network_code = "cuttlefish" + web_property = "mussel" + expected = "networks/{network_code}/webProperties/{web_property}".format( + network_code=network_code, + web_property=web_property, + ) + actual = AdReviewCenterAdServiceClient.web_property_path(network_code, web_property) + assert expected == actual + + +def test_parse_web_property_path(): + expected = { + "network_code": "winkle", + "web_property": "nautilus", + } + path = AdReviewCenterAdServiceClient.web_property_path(**expected) + + # Check that the path construction is reversible. + actual = AdReviewCenterAdServiceClient.parse_web_property_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "scallop" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = AdReviewCenterAdServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "abalone", + } + path = AdReviewCenterAdServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = AdReviewCenterAdServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "squid" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = AdReviewCenterAdServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "clam", + } + path = AdReviewCenterAdServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = AdReviewCenterAdServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "whelk" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = AdReviewCenterAdServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "octopus", + } + path = AdReviewCenterAdServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = AdReviewCenterAdServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "oyster" + expected = "projects/{project}".format( + project=project, + ) + actual = AdReviewCenterAdServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nudibranch", + } + path = AdReviewCenterAdServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = AdReviewCenterAdServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "cuttlefish" + location = "mussel" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = AdReviewCenterAdServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "winkle", + "location": "nautilus", + } + path = AdReviewCenterAdServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = AdReviewCenterAdServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.AdReviewCenterAdServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.AdReviewCenterAdServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = AdReviewCenterAdServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_rest(): + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + ] + for transport in transports: + client = AdReviewCenterAdServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + ( + AdReviewCenterAdServiceClient, + transports.AdReviewCenterAdServiceRestTransport, + ), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_application_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_application_service.py new file mode 100644 index 000000000000..0d771ae61bea --- /dev/null +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_application_service.py @@ -0,0 +1,2269 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account + +from google.ads.admanager_v1.services.application_service import ( + ApplicationServiceClient, + pagers, + transports, +) +from google.ads.admanager_v1.types import application_messages, application_service + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert ApplicationServiceClient._get_default_mtls_endpoint(None) is None + assert ( + ApplicationServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + ApplicationServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + ApplicationServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + ApplicationServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + ApplicationServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +def test__read_environment_variables(): + assert ApplicationServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert ApplicationServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert ApplicationServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + ApplicationServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert ApplicationServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert ApplicationServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert ApplicationServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + ApplicationServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert ApplicationServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert ApplicationServiceClient._get_client_cert_source(None, False) is None + assert ( + ApplicationServiceClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + ApplicationServiceClient._get_client_cert_source( + mock_provided_cert_source, True + ) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + ApplicationServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + ApplicationServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + ApplicationServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ApplicationServiceClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = ApplicationServiceClient._DEFAULT_UNIVERSE + default_endpoint = ApplicationServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = ApplicationServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + ApplicationServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + ApplicationServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == ApplicationServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + ApplicationServiceClient._get_api_endpoint(None, None, default_universe, "auto") + == default_endpoint + ) + assert ( + ApplicationServiceClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == ApplicationServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + ApplicationServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == ApplicationServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + ApplicationServiceClient._get_api_endpoint(None, None, mock_universe, "never") + == mock_endpoint + ) + assert ( + ApplicationServiceClient._get_api_endpoint( + None, None, default_universe, "never" + ) + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + ApplicationServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + ApplicationServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + ApplicationServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + ApplicationServiceClient._get_universe_domain(None, None) + == ApplicationServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + ApplicationServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ApplicationServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ApplicationServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (ApplicationServiceClient, "rest"), + ], +) +def test_application_service_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.ApplicationServiceRestTransport, "rest"), + ], +) +def test_application_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (ApplicationServiceClient, "rest"), + ], +) +def test_application_service_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +def test_application_service_client_get_transport_class(): + transport = ApplicationServiceClient.get_transport_class() + available_transports = [ + transports.ApplicationServiceRestTransport, + ] + assert transport in available_transports + + transport = ApplicationServiceClient.get_transport_class("rest") + assert transport == transports.ApplicationServiceRestTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (ApplicationServiceClient, transports.ApplicationServiceRestTransport, "rest"), + ], +) +@mock.patch.object( + ApplicationServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ApplicationServiceClient), +) +def test_application_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(ApplicationServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(ApplicationServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + ApplicationServiceClient, + transports.ApplicationServiceRestTransport, + "rest", + "true", + ), + ( + ApplicationServiceClient, + transports.ApplicationServiceRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + ApplicationServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ApplicationServiceClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_application_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [ApplicationServiceClient]) +@mock.patch.object( + ApplicationServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(ApplicationServiceClient), +) +def test_application_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize("client_class", [ApplicationServiceClient]) +@mock.patch.object( + ApplicationServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ApplicationServiceClient), +) +def test_application_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = ApplicationServiceClient._DEFAULT_UNIVERSE + default_endpoint = ApplicationServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = ApplicationServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (ApplicationServiceClient, transports.ApplicationServiceRestTransport, "rest"), + ], +) +def test_application_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + ApplicationServiceClient, + transports.ApplicationServiceRestTransport, + "rest", + None, + ), + ], +) +def test_application_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_get_application_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_application in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_application] = mock_rpc + + request = {} + client.get_application(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_application(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_application_rest_required_fields( + request_type=application_service.GetApplicationRequest, +): + transport_class = transports.ApplicationServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_application._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_application._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = application_messages.Application() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = application_messages.Application.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_application(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_application_rest_unset_required_fields(): + transport = transports.ApplicationServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_application._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_application_rest_flattened(): + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = application_messages.Application() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "networks/sample1/applications/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = application_messages.Application.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_application(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=networks/*/applications/*}" % client.transport._host, args[1] + ) + + +def test_get_application_rest_flattened_error(transport: str = "rest"): + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_application( + application_service.GetApplicationRequest(), + name="name_value", + ) + + +def test_list_applications_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_applications in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_applications + ] = mock_rpc + + request = {} + client.list_applications(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_applications(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_applications_rest_required_fields( + request_type=application_service.ListApplicationsRequest, +): + transport_class = transports.ApplicationServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_applications._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_applications._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + "skip", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = application_service.ListApplicationsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = application_service.ListApplicationsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_applications(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_applications_rest_unset_required_fields(): + transport = transports.ApplicationServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_applications._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + "skip", + ) + ) + & set(("parent",)) + ) + + +def test_list_applications_rest_flattened(): + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = application_service.ListApplicationsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = application_service.ListApplicationsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_applications(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/applications" % client.transport._host, args[1] + ) + + +def test_list_applications_rest_flattened_error(transport: str = "rest"): + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_applications( + application_service.ListApplicationsRequest(), + parent="parent_value", + ) + + +def test_list_applications_rest_pager(transport: str = "rest"): + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + application_service.ListApplicationsResponse( + applications=[ + application_messages.Application(), + application_messages.Application(), + application_messages.Application(), + ], + next_page_token="abc", + ), + application_service.ListApplicationsResponse( + applications=[], + next_page_token="def", + ), + application_service.ListApplicationsResponse( + applications=[ + application_messages.Application(), + ], + next_page_token="ghi", + ), + application_service.ListApplicationsResponse( + applications=[ + application_messages.Application(), + application_messages.Application(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + application_service.ListApplicationsResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "networks/sample1"} + + pager = client.list_applications(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, application_messages.Application) for i in results) + + pages = list(client.list_applications(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ApplicationServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ApplicationServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ApplicationServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ApplicationServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ApplicationServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ApplicationServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ApplicationServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ApplicationServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ApplicationServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ApplicationServiceClient(transport=transport) + assert client.transport is transport + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ApplicationServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_rest(): + transport = ApplicationServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_application_rest_bad_request( + request_type=application_service.GetApplicationRequest, +): + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/applications/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_application(request) + + +@pytest.mark.parametrize( + "request_type", + [ + application_service.GetApplicationRequest, + dict, + ], +) +def test_get_application_rest_call_success(request_type): + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/applications/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = application_messages.Application( + name="name_value", + display_name="display_name_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = application_messages.Application.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_application(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, application_messages.Application) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_application_rest_interceptors(null_interceptor): + transport = transports.ApplicationServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ApplicationServiceRestInterceptor(), + ) + client = ApplicationServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ApplicationServiceRestInterceptor, "post_get_application" + ) as post, mock.patch.object( + transports.ApplicationServiceRestInterceptor, + "post_get_application_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.ApplicationServiceRestInterceptor, "pre_get_application" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = application_service.GetApplicationRequest.pb( + application_service.GetApplicationRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = application_messages.Application.to_json( + application_messages.Application() + ) + req.return_value.content = return_value + + request = application_service.GetApplicationRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = application_messages.Application() + post_with_metadata.return_value = application_messages.Application(), metadata + + client.get_application( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_applications_rest_bad_request( + request_type=application_service.ListApplicationsRequest, +): + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_applications(request) + + +@pytest.mark.parametrize( + "request_type", + [ + application_service.ListApplicationsRequest, + dict, + ], +) +def test_list_applications_rest_call_success(request_type): + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = application_service.ListApplicationsResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = application_service.ListApplicationsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_applications(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListApplicationsPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_applications_rest_interceptors(null_interceptor): + transport = transports.ApplicationServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ApplicationServiceRestInterceptor(), + ) + client = ApplicationServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ApplicationServiceRestInterceptor, "post_list_applications" + ) as post, mock.patch.object( + transports.ApplicationServiceRestInterceptor, + "post_list_applications_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.ApplicationServiceRestInterceptor, "pre_list_applications" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = application_service.ListApplicationsRequest.pb( + application_service.ListApplicationsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = application_service.ListApplicationsResponse.to_json( + application_service.ListApplicationsResponse() + ) + req.return_value.content = return_value + + request = application_service.ListApplicationsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = application_service.ListApplicationsResponse() + post_with_metadata.return_value = ( + application_service.ListApplicationsResponse(), + metadata, + ) + + client.list_applications( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "networks/sample1/operations/reports/runs/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "networks/sample1/operations/reports/runs/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_initialize_client_w_rest(): + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_application_empty_call_rest(): + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_application), "__call__") as call: + client.get_application(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = application_service.GetApplicationRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_applications_empty_call_rest(): + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_applications), "__call__" + ) as call: + client.list_applications(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = application_service.ListApplicationsRequest() + + assert args[0] == request_msg + + +def test_application_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ApplicationServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_application_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.ads.admanager_v1.services.application_service.transports.ApplicationServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.ApplicationServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "get_application", + "list_applications", + "get_operation", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_application_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.ads.admanager_v1.services.application_service.transports.ApplicationServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ApplicationServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id="octopus", + ) + + +def test_application_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.ads.admanager_v1.services.application_service.transports.ApplicationServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ApplicationServiceTransport() + adc.assert_called_once() + + +def test_application_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + ApplicationServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id=None, + ) + + +def test_application_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.ApplicationServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_application_service_host_no_port(transport_name): + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_application_service_host_with_port(transport_name): + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_application_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ApplicationServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ApplicationServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.get_application._session + session2 = client2.transport.get_application._session + assert session1 != session2 + session1 = client1.transport.list_applications._session + session2 = client2.transport.list_applications._session + assert session1 != session2 + + +def test_application_path(): + network_code = "squid" + application = "clam" + expected = "networks/{network_code}/applications/{application}".format( + network_code=network_code, + application=application, + ) + actual = ApplicationServiceClient.application_path(network_code, application) + assert expected == actual + + +def test_parse_application_path(): + expected = { + "network_code": "whelk", + "application": "octopus", + } + path = ApplicationServiceClient.application_path(**expected) + + # Check that the path construction is reversible. + actual = ApplicationServiceClient.parse_application_path(path) + assert expected == actual + + +def test_network_path(): + network_code = "oyster" + expected = "networks/{network_code}".format( + network_code=network_code, + ) + actual = ApplicationServiceClient.network_path(network_code) + assert expected == actual + + +def test_parse_network_path(): + expected = { + "network_code": "nudibranch", + } + path = ApplicationServiceClient.network_path(**expected) + + # Check that the path construction is reversible. + actual = ApplicationServiceClient.parse_network_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = ApplicationServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = ApplicationServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ApplicationServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = ApplicationServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = ApplicationServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ApplicationServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = ApplicationServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = ApplicationServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ApplicationServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format( + project=project, + ) + actual = ApplicationServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = ApplicationServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ApplicationServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = ApplicationServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = ApplicationServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ApplicationServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.ApplicationServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.ApplicationServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = ApplicationServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_rest(): + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + ] + for transport in transports: + client = ApplicationServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (ApplicationServiceClient, transports.ApplicationServiceRestTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_audience_segment_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_audience_segment_service.py new file mode 100644 index 000000000000..93943cbaa8d1 --- /dev/null +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_audience_segment_service.py @@ -0,0 +1,2311 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account + +from google.ads.admanager_v1.services.audience_segment_service import ( + AudienceSegmentServiceClient, + pagers, + transports, +) +from google.ads.admanager_v1.types import ( + audience_segment_messages, + audience_segment_service, +) + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert AudienceSegmentServiceClient._get_default_mtls_endpoint(None) is None + assert ( + AudienceSegmentServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + AudienceSegmentServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + AudienceSegmentServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + AudienceSegmentServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + AudienceSegmentServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +def test__read_environment_variables(): + assert AudienceSegmentServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert AudienceSegmentServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert AudienceSegmentServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + AudienceSegmentServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert AudienceSegmentServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert AudienceSegmentServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert AudienceSegmentServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + AudienceSegmentServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert AudienceSegmentServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert AudienceSegmentServiceClient._get_client_cert_source(None, False) is None + assert ( + AudienceSegmentServiceClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + AudienceSegmentServiceClient._get_client_cert_source( + mock_provided_cert_source, True + ) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + AudienceSegmentServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + AudienceSegmentServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + AudienceSegmentServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AudienceSegmentServiceClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = AudienceSegmentServiceClient._DEFAULT_UNIVERSE + default_endpoint = AudienceSegmentServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = AudienceSegmentServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + AudienceSegmentServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + AudienceSegmentServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == AudienceSegmentServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + AudienceSegmentServiceClient._get_api_endpoint( + None, None, default_universe, "auto" + ) + == default_endpoint + ) + assert ( + AudienceSegmentServiceClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == AudienceSegmentServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + AudienceSegmentServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == AudienceSegmentServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + AudienceSegmentServiceClient._get_api_endpoint( + None, None, mock_universe, "never" + ) + == mock_endpoint + ) + assert ( + AudienceSegmentServiceClient._get_api_endpoint( + None, None, default_universe, "never" + ) + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + AudienceSegmentServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + AudienceSegmentServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + AudienceSegmentServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + AudienceSegmentServiceClient._get_universe_domain(None, None) + == AudienceSegmentServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + AudienceSegmentServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = AudienceSegmentServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = AudienceSegmentServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (AudienceSegmentServiceClient, "rest"), + ], +) +def test_audience_segment_service_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.AudienceSegmentServiceRestTransport, "rest"), + ], +) +def test_audience_segment_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (AudienceSegmentServiceClient, "rest"), + ], +) +def test_audience_segment_service_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +def test_audience_segment_service_client_get_transport_class(): + transport = AudienceSegmentServiceClient.get_transport_class() + available_transports = [ + transports.AudienceSegmentServiceRestTransport, + ] + assert transport in available_transports + + transport = AudienceSegmentServiceClient.get_transport_class("rest") + assert transport == transports.AudienceSegmentServiceRestTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + AudienceSegmentServiceClient, + transports.AudienceSegmentServiceRestTransport, + "rest", + ), + ], +) +@mock.patch.object( + AudienceSegmentServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AudienceSegmentServiceClient), +) +def test_audience_segment_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(AudienceSegmentServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(AudienceSegmentServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + AudienceSegmentServiceClient, + transports.AudienceSegmentServiceRestTransport, + "rest", + "true", + ), + ( + AudienceSegmentServiceClient, + transports.AudienceSegmentServiceRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + AudienceSegmentServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AudienceSegmentServiceClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_audience_segment_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [AudienceSegmentServiceClient]) +@mock.patch.object( + AudienceSegmentServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(AudienceSegmentServiceClient), +) +def test_audience_segment_service_client_get_mtls_endpoint_and_cert_source( + client_class, +): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize("client_class", [AudienceSegmentServiceClient]) +@mock.patch.object( + AudienceSegmentServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(AudienceSegmentServiceClient), +) +def test_audience_segment_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = AudienceSegmentServiceClient._DEFAULT_UNIVERSE + default_endpoint = AudienceSegmentServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = AudienceSegmentServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + AudienceSegmentServiceClient, + transports.AudienceSegmentServiceRestTransport, + "rest", + ), + ], +) +def test_audience_segment_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + AudienceSegmentServiceClient, + transports.AudienceSegmentServiceRestTransport, + "rest", + None, + ), + ], +) +def test_audience_segment_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_get_audience_segment_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_audience_segment in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_audience_segment + ] = mock_rpc + + request = {} + client.get_audience_segment(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_audience_segment(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_audience_segment_rest_required_fields( + request_type=audience_segment_service.GetAudienceSegmentRequest, +): + transport_class = transports.AudienceSegmentServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_audience_segment._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_audience_segment._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = audience_segment_messages.AudienceSegment() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = audience_segment_messages.AudienceSegment.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_audience_segment(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_audience_segment_rest_unset_required_fields(): + transport = transports.AudienceSegmentServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_audience_segment._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_audience_segment_rest_flattened(): + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = audience_segment_messages.AudienceSegment() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "networks/sample1/audienceSegments/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = audience_segment_messages.AudienceSegment.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_audience_segment(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=networks/*/audienceSegments/*}" % client.transport._host, + args[1], + ) + + +def test_get_audience_segment_rest_flattened_error(transport: str = "rest"): + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_audience_segment( + audience_segment_service.GetAudienceSegmentRequest(), + name="name_value", + ) + + +def test_list_audience_segments_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_audience_segments + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_audience_segments + ] = mock_rpc + + request = {} + client.list_audience_segments(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_audience_segments(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_audience_segments_rest_required_fields( + request_type=audience_segment_service.ListAudienceSegmentsRequest, +): + transport_class = transports.AudienceSegmentServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_audience_segments._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_audience_segments._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + "skip", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = audience_segment_service.ListAudienceSegmentsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = audience_segment_service.ListAudienceSegmentsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_audience_segments(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_audience_segments_rest_unset_required_fields(): + transport = transports.AudienceSegmentServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_audience_segments._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + "skip", + ) + ) + & set(("parent",)) + ) + + +def test_list_audience_segments_rest_flattened(): + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = audience_segment_service.ListAudienceSegmentsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = audience_segment_service.ListAudienceSegmentsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_audience_segments(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/audienceSegments" % client.transport._host, + args[1], + ) + + +def test_list_audience_segments_rest_flattened_error(transport: str = "rest"): + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_audience_segments( + audience_segment_service.ListAudienceSegmentsRequest(), + parent="parent_value", + ) + + +def test_list_audience_segments_rest_pager(transport: str = "rest"): + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + audience_segment_service.ListAudienceSegmentsResponse( + audience_segments=[ + audience_segment_messages.AudienceSegment(), + audience_segment_messages.AudienceSegment(), + audience_segment_messages.AudienceSegment(), + ], + next_page_token="abc", + ), + audience_segment_service.ListAudienceSegmentsResponse( + audience_segments=[], + next_page_token="def", + ), + audience_segment_service.ListAudienceSegmentsResponse( + audience_segments=[ + audience_segment_messages.AudienceSegment(), + ], + next_page_token="ghi", + ), + audience_segment_service.ListAudienceSegmentsResponse( + audience_segments=[ + audience_segment_messages.AudienceSegment(), + audience_segment_messages.AudienceSegment(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + audience_segment_service.ListAudienceSegmentsResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "networks/sample1"} + + pager = client.list_audience_segments(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, audience_segment_messages.AudienceSegment) for i in results + ) + + pages = list(client.list_audience_segments(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.AudienceSegmentServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.AudienceSegmentServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AudienceSegmentServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.AudienceSegmentServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = AudienceSegmentServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = AudienceSegmentServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.AudienceSegmentServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = AudienceSegmentServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.AudienceSegmentServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = AudienceSegmentServiceClient(transport=transport) + assert client.transport is transport + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.AudienceSegmentServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_rest(): + transport = AudienceSegmentServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_audience_segment_rest_bad_request( + request_type=audience_segment_service.GetAudienceSegmentRequest, +): + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/audienceSegments/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_audience_segment(request) + + +@pytest.mark.parametrize( + "request_type", + [ + audience_segment_service.GetAudienceSegmentRequest, + dict, + ], +) +def test_get_audience_segment_rest_call_success(request_type): + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/audienceSegments/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = audience_segment_messages.AudienceSegment( + name="name_value", + display_name="display_name_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = audience_segment_messages.AudienceSegment.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_audience_segment(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, audience_segment_messages.AudienceSegment) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_audience_segment_rest_interceptors(null_interceptor): + transport = transports.AudienceSegmentServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.AudienceSegmentServiceRestInterceptor(), + ) + client = AudienceSegmentServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.AudienceSegmentServiceRestInterceptor, "post_get_audience_segment" + ) as post, mock.patch.object( + transports.AudienceSegmentServiceRestInterceptor, + "post_get_audience_segment_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.AudienceSegmentServiceRestInterceptor, "pre_get_audience_segment" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = audience_segment_service.GetAudienceSegmentRequest.pb( + audience_segment_service.GetAudienceSegmentRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = audience_segment_messages.AudienceSegment.to_json( + audience_segment_messages.AudienceSegment() + ) + req.return_value.content = return_value + + request = audience_segment_service.GetAudienceSegmentRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = audience_segment_messages.AudienceSegment() + post_with_metadata.return_value = ( + audience_segment_messages.AudienceSegment(), + metadata, + ) + + client.get_audience_segment( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_audience_segments_rest_bad_request( + request_type=audience_segment_service.ListAudienceSegmentsRequest, +): + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_audience_segments(request) + + +@pytest.mark.parametrize( + "request_type", + [ + audience_segment_service.ListAudienceSegmentsRequest, + dict, + ], +) +def test_list_audience_segments_rest_call_success(request_type): + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = audience_segment_service.ListAudienceSegmentsResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = audience_segment_service.ListAudienceSegmentsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_audience_segments(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListAudienceSegmentsPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_audience_segments_rest_interceptors(null_interceptor): + transport = transports.AudienceSegmentServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.AudienceSegmentServiceRestInterceptor(), + ) + client = AudienceSegmentServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.AudienceSegmentServiceRestInterceptor, "post_list_audience_segments" + ) as post, mock.patch.object( + transports.AudienceSegmentServiceRestInterceptor, + "post_list_audience_segments_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.AudienceSegmentServiceRestInterceptor, "pre_list_audience_segments" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = audience_segment_service.ListAudienceSegmentsRequest.pb( + audience_segment_service.ListAudienceSegmentsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = audience_segment_service.ListAudienceSegmentsResponse.to_json( + audience_segment_service.ListAudienceSegmentsResponse() + ) + req.return_value.content = return_value + + request = audience_segment_service.ListAudienceSegmentsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = audience_segment_service.ListAudienceSegmentsResponse() + post_with_metadata.return_value = ( + audience_segment_service.ListAudienceSegmentsResponse(), + metadata, + ) + + client.list_audience_segments( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "networks/sample1/operations/reports/runs/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "networks/sample1/operations/reports/runs/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_initialize_client_w_rest(): + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_audience_segment_empty_call_rest(): + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_audience_segment), "__call__" + ) as call: + client.get_audience_segment(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = audience_segment_service.GetAudienceSegmentRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_audience_segments_empty_call_rest(): + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_audience_segments), "__call__" + ) as call: + client.list_audience_segments(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = audience_segment_service.ListAudienceSegmentsRequest() + + assert args[0] == request_msg + + +def test_audience_segment_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.AudienceSegmentServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_audience_segment_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.ads.admanager_v1.services.audience_segment_service.transports.AudienceSegmentServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.AudienceSegmentServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "get_audience_segment", + "list_audience_segments", + "get_operation", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_audience_segment_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.ads.admanager_v1.services.audience_segment_service.transports.AudienceSegmentServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.AudienceSegmentServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id="octopus", + ) + + +def test_audience_segment_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.ads.admanager_v1.services.audience_segment_service.transports.AudienceSegmentServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.AudienceSegmentServiceTransport() + adc.assert_called_once() + + +def test_audience_segment_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + AudienceSegmentServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id=None, + ) + + +def test_audience_segment_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.AudienceSegmentServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_audience_segment_service_host_no_port(transport_name): + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_audience_segment_service_host_with_port(transport_name): + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_audience_segment_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = AudienceSegmentServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = AudienceSegmentServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.get_audience_segment._session + session2 = client2.transport.get_audience_segment._session + assert session1 != session2 + session1 = client1.transport.list_audience_segments._session + session2 = client2.transport.list_audience_segments._session + assert session1 != session2 + + +def test_audience_segment_path(): + network_code = "squid" + audience_segment = "clam" + expected = "networks/{network_code}/audienceSegments/{audience_segment}".format( + network_code=network_code, + audience_segment=audience_segment, + ) + actual = AudienceSegmentServiceClient.audience_segment_path( + network_code, audience_segment + ) + assert expected == actual + + +def test_parse_audience_segment_path(): + expected = { + "network_code": "whelk", + "audience_segment": "octopus", + } + path = AudienceSegmentServiceClient.audience_segment_path(**expected) + + # Check that the path construction is reversible. + actual = AudienceSegmentServiceClient.parse_audience_segment_path(path) + assert expected == actual + + +def test_network_path(): + network_code = "oyster" + expected = "networks/{network_code}".format( + network_code=network_code, + ) + actual = AudienceSegmentServiceClient.network_path(network_code) + assert expected == actual + + +def test_parse_network_path(): + expected = { + "network_code": "nudibranch", + } + path = AudienceSegmentServiceClient.network_path(**expected) + + # Check that the path construction is reversible. + actual = AudienceSegmentServiceClient.parse_network_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = AudienceSegmentServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = AudienceSegmentServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = AudienceSegmentServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = AudienceSegmentServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = AudienceSegmentServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = AudienceSegmentServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = AudienceSegmentServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = AudienceSegmentServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = AudienceSegmentServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format( + project=project, + ) + actual = AudienceSegmentServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = AudienceSegmentServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = AudienceSegmentServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = AudienceSegmentServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = AudienceSegmentServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = AudienceSegmentServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.AudienceSegmentServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.AudienceSegmentServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = AudienceSegmentServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_rest(): + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + ] + for transport in transports: + client = AudienceSegmentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (AudienceSegmentServiceClient, transports.AudienceSegmentServiceRestTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_browser_language_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_browser_language_service.py new file mode 100644 index 000000000000..85c387755a79 --- /dev/null +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_browser_language_service.py @@ -0,0 +1,2311 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account + +from google.ads.admanager_v1.services.browser_language_service import ( + BrowserLanguageServiceClient, + pagers, + transports, +) +from google.ads.admanager_v1.types import ( + browser_language_messages, + browser_language_service, +) + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert BrowserLanguageServiceClient._get_default_mtls_endpoint(None) is None + assert ( + BrowserLanguageServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + BrowserLanguageServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + BrowserLanguageServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + BrowserLanguageServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + BrowserLanguageServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +def test__read_environment_variables(): + assert BrowserLanguageServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert BrowserLanguageServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert BrowserLanguageServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + BrowserLanguageServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert BrowserLanguageServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert BrowserLanguageServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert BrowserLanguageServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + BrowserLanguageServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert BrowserLanguageServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert BrowserLanguageServiceClient._get_client_cert_source(None, False) is None + assert ( + BrowserLanguageServiceClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + BrowserLanguageServiceClient._get_client_cert_source( + mock_provided_cert_source, True + ) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + BrowserLanguageServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + BrowserLanguageServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + BrowserLanguageServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(BrowserLanguageServiceClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = BrowserLanguageServiceClient._DEFAULT_UNIVERSE + default_endpoint = BrowserLanguageServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = BrowserLanguageServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + BrowserLanguageServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + BrowserLanguageServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == BrowserLanguageServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + BrowserLanguageServiceClient._get_api_endpoint( + None, None, default_universe, "auto" + ) + == default_endpoint + ) + assert ( + BrowserLanguageServiceClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == BrowserLanguageServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + BrowserLanguageServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == BrowserLanguageServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + BrowserLanguageServiceClient._get_api_endpoint( + None, None, mock_universe, "never" + ) + == mock_endpoint + ) + assert ( + BrowserLanguageServiceClient._get_api_endpoint( + None, None, default_universe, "never" + ) + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + BrowserLanguageServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + BrowserLanguageServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + BrowserLanguageServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + BrowserLanguageServiceClient._get_universe_domain(None, None) + == BrowserLanguageServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + BrowserLanguageServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = BrowserLanguageServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = BrowserLanguageServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (BrowserLanguageServiceClient, "rest"), + ], +) +def test_browser_language_service_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.BrowserLanguageServiceRestTransport, "rest"), + ], +) +def test_browser_language_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (BrowserLanguageServiceClient, "rest"), + ], +) +def test_browser_language_service_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +def test_browser_language_service_client_get_transport_class(): + transport = BrowserLanguageServiceClient.get_transport_class() + available_transports = [ + transports.BrowserLanguageServiceRestTransport, + ] + assert transport in available_transports + + transport = BrowserLanguageServiceClient.get_transport_class("rest") + assert transport == transports.BrowserLanguageServiceRestTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + BrowserLanguageServiceClient, + transports.BrowserLanguageServiceRestTransport, + "rest", + ), + ], +) +@mock.patch.object( + BrowserLanguageServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(BrowserLanguageServiceClient), +) +def test_browser_language_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(BrowserLanguageServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(BrowserLanguageServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + BrowserLanguageServiceClient, + transports.BrowserLanguageServiceRestTransport, + "rest", + "true", + ), + ( + BrowserLanguageServiceClient, + transports.BrowserLanguageServiceRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + BrowserLanguageServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(BrowserLanguageServiceClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_browser_language_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [BrowserLanguageServiceClient]) +@mock.patch.object( + BrowserLanguageServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(BrowserLanguageServiceClient), +) +def test_browser_language_service_client_get_mtls_endpoint_and_cert_source( + client_class, +): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize("client_class", [BrowserLanguageServiceClient]) +@mock.patch.object( + BrowserLanguageServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(BrowserLanguageServiceClient), +) +def test_browser_language_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = BrowserLanguageServiceClient._DEFAULT_UNIVERSE + default_endpoint = BrowserLanguageServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = BrowserLanguageServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + BrowserLanguageServiceClient, + transports.BrowserLanguageServiceRestTransport, + "rest", + ), + ], +) +def test_browser_language_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + BrowserLanguageServiceClient, + transports.BrowserLanguageServiceRestTransport, + "rest", + None, + ), + ], +) +def test_browser_language_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_get_browser_language_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_browser_language in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_browser_language + ] = mock_rpc + + request = {} + client.get_browser_language(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_browser_language(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_browser_language_rest_required_fields( + request_type=browser_language_service.GetBrowserLanguageRequest, +): + transport_class = transports.BrowserLanguageServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_browser_language._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_browser_language._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = browser_language_messages.BrowserLanguage() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = browser_language_messages.BrowserLanguage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_browser_language(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_browser_language_rest_unset_required_fields(): + transport = transports.BrowserLanguageServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_browser_language._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_browser_language_rest_flattened(): + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = browser_language_messages.BrowserLanguage() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "networks/sample1/browserLanguages/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = browser_language_messages.BrowserLanguage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_browser_language(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=networks/*/browserLanguages/*}" % client.transport._host, + args[1], + ) + + +def test_get_browser_language_rest_flattened_error(transport: str = "rest"): + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_browser_language( + browser_language_service.GetBrowserLanguageRequest(), + name="name_value", + ) + + +def test_list_browser_languages_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_browser_languages + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_browser_languages + ] = mock_rpc + + request = {} + client.list_browser_languages(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_browser_languages(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_browser_languages_rest_required_fields( + request_type=browser_language_service.ListBrowserLanguagesRequest, +): + transport_class = transports.BrowserLanguageServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_browser_languages._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_browser_languages._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + "skip", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = browser_language_service.ListBrowserLanguagesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = browser_language_service.ListBrowserLanguagesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_browser_languages(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_browser_languages_rest_unset_required_fields(): + transport = transports.BrowserLanguageServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_browser_languages._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + "skip", + ) + ) + & set(("parent",)) + ) + + +def test_list_browser_languages_rest_flattened(): + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = browser_language_service.ListBrowserLanguagesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = browser_language_service.ListBrowserLanguagesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_browser_languages(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/browserLanguages" % client.transport._host, + args[1], + ) + + +def test_list_browser_languages_rest_flattened_error(transport: str = "rest"): + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_browser_languages( + browser_language_service.ListBrowserLanguagesRequest(), + parent="parent_value", + ) + + +def test_list_browser_languages_rest_pager(transport: str = "rest"): + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + browser_language_service.ListBrowserLanguagesResponse( + browser_languages=[ + browser_language_messages.BrowserLanguage(), + browser_language_messages.BrowserLanguage(), + browser_language_messages.BrowserLanguage(), + ], + next_page_token="abc", + ), + browser_language_service.ListBrowserLanguagesResponse( + browser_languages=[], + next_page_token="def", + ), + browser_language_service.ListBrowserLanguagesResponse( + browser_languages=[ + browser_language_messages.BrowserLanguage(), + ], + next_page_token="ghi", + ), + browser_language_service.ListBrowserLanguagesResponse( + browser_languages=[ + browser_language_messages.BrowserLanguage(), + browser_language_messages.BrowserLanguage(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + browser_language_service.ListBrowserLanguagesResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "networks/sample1"} + + pager = client.list_browser_languages(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, browser_language_messages.BrowserLanguage) for i in results + ) + + pages = list(client.list_browser_languages(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.BrowserLanguageServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.BrowserLanguageServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = BrowserLanguageServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.BrowserLanguageServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = BrowserLanguageServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = BrowserLanguageServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.BrowserLanguageServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = BrowserLanguageServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.BrowserLanguageServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = BrowserLanguageServiceClient(transport=transport) + assert client.transport is transport + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.BrowserLanguageServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_rest(): + transport = BrowserLanguageServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_browser_language_rest_bad_request( + request_type=browser_language_service.GetBrowserLanguageRequest, +): + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/browserLanguages/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_browser_language(request) + + +@pytest.mark.parametrize( + "request_type", + [ + browser_language_service.GetBrowserLanguageRequest, + dict, + ], +) +def test_get_browser_language_rest_call_success(request_type): + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/browserLanguages/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = browser_language_messages.BrowserLanguage( + name="name_value", + display_name="display_name_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = browser_language_messages.BrowserLanguage.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_browser_language(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, browser_language_messages.BrowserLanguage) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_browser_language_rest_interceptors(null_interceptor): + transport = transports.BrowserLanguageServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.BrowserLanguageServiceRestInterceptor(), + ) + client = BrowserLanguageServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.BrowserLanguageServiceRestInterceptor, "post_get_browser_language" + ) as post, mock.patch.object( + transports.BrowserLanguageServiceRestInterceptor, + "post_get_browser_language_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.BrowserLanguageServiceRestInterceptor, "pre_get_browser_language" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = browser_language_service.GetBrowserLanguageRequest.pb( + browser_language_service.GetBrowserLanguageRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = browser_language_messages.BrowserLanguage.to_json( + browser_language_messages.BrowserLanguage() + ) + req.return_value.content = return_value + + request = browser_language_service.GetBrowserLanguageRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = browser_language_messages.BrowserLanguage() + post_with_metadata.return_value = ( + browser_language_messages.BrowserLanguage(), + metadata, + ) + + client.get_browser_language( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_browser_languages_rest_bad_request( + request_type=browser_language_service.ListBrowserLanguagesRequest, +): + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_browser_languages(request) + + +@pytest.mark.parametrize( + "request_type", + [ + browser_language_service.ListBrowserLanguagesRequest, + dict, + ], +) +def test_list_browser_languages_rest_call_success(request_type): + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = browser_language_service.ListBrowserLanguagesResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = browser_language_service.ListBrowserLanguagesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_browser_languages(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListBrowserLanguagesPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_browser_languages_rest_interceptors(null_interceptor): + transport = transports.BrowserLanguageServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.BrowserLanguageServiceRestInterceptor(), + ) + client = BrowserLanguageServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.BrowserLanguageServiceRestInterceptor, "post_list_browser_languages" + ) as post, mock.patch.object( + transports.BrowserLanguageServiceRestInterceptor, + "post_list_browser_languages_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.BrowserLanguageServiceRestInterceptor, "pre_list_browser_languages" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = browser_language_service.ListBrowserLanguagesRequest.pb( + browser_language_service.ListBrowserLanguagesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = browser_language_service.ListBrowserLanguagesResponse.to_json( + browser_language_service.ListBrowserLanguagesResponse() + ) + req.return_value.content = return_value + + request = browser_language_service.ListBrowserLanguagesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = browser_language_service.ListBrowserLanguagesResponse() + post_with_metadata.return_value = ( + browser_language_service.ListBrowserLanguagesResponse(), + metadata, + ) + + client.list_browser_languages( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "networks/sample1/operations/reports/runs/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "networks/sample1/operations/reports/runs/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_initialize_client_w_rest(): + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_browser_language_empty_call_rest(): + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_browser_language), "__call__" + ) as call: + client.get_browser_language(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = browser_language_service.GetBrowserLanguageRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_browser_languages_empty_call_rest(): + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_browser_languages), "__call__" + ) as call: + client.list_browser_languages(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = browser_language_service.ListBrowserLanguagesRequest() + + assert args[0] == request_msg + + +def test_browser_language_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.BrowserLanguageServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_browser_language_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.ads.admanager_v1.services.browser_language_service.transports.BrowserLanguageServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.BrowserLanguageServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "get_browser_language", + "list_browser_languages", + "get_operation", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_browser_language_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.ads.admanager_v1.services.browser_language_service.transports.BrowserLanguageServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.BrowserLanguageServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id="octopus", + ) + + +def test_browser_language_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.ads.admanager_v1.services.browser_language_service.transports.BrowserLanguageServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.BrowserLanguageServiceTransport() + adc.assert_called_once() + + +def test_browser_language_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + BrowserLanguageServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id=None, + ) + + +def test_browser_language_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.BrowserLanguageServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_browser_language_service_host_no_port(transport_name): + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_browser_language_service_host_with_port(transport_name): + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_browser_language_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = BrowserLanguageServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = BrowserLanguageServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.get_browser_language._session + session2 = client2.transport.get_browser_language._session + assert session1 != session2 + session1 = client1.transport.list_browser_languages._session + session2 = client2.transport.list_browser_languages._session + assert session1 != session2 + + +def test_browser_language_path(): + network_code = "squid" + browser_language = "clam" + expected = "networks/{network_code}/browserLanguages/{browser_language}".format( + network_code=network_code, + browser_language=browser_language, + ) + actual = BrowserLanguageServiceClient.browser_language_path( + network_code, browser_language + ) + assert expected == actual + + +def test_parse_browser_language_path(): + expected = { + "network_code": "whelk", + "browser_language": "octopus", + } + path = BrowserLanguageServiceClient.browser_language_path(**expected) + + # Check that the path construction is reversible. + actual = BrowserLanguageServiceClient.parse_browser_language_path(path) + assert expected == actual + + +def test_network_path(): + network_code = "oyster" + expected = "networks/{network_code}".format( + network_code=network_code, + ) + actual = BrowserLanguageServiceClient.network_path(network_code) + assert expected == actual + + +def test_parse_network_path(): + expected = { + "network_code": "nudibranch", + } + path = BrowserLanguageServiceClient.network_path(**expected) + + # Check that the path construction is reversible. + actual = BrowserLanguageServiceClient.parse_network_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = BrowserLanguageServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = BrowserLanguageServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = BrowserLanguageServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = BrowserLanguageServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = BrowserLanguageServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = BrowserLanguageServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = BrowserLanguageServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = BrowserLanguageServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = BrowserLanguageServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format( + project=project, + ) + actual = BrowserLanguageServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = BrowserLanguageServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = BrowserLanguageServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = BrowserLanguageServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = BrowserLanguageServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = BrowserLanguageServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.BrowserLanguageServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.BrowserLanguageServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = BrowserLanguageServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_rest(): + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + ] + for transport in transports: + client = BrowserLanguageServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (BrowserLanguageServiceClient, transports.BrowserLanguageServiceRestTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_browser_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_browser_service.py new file mode 100644 index 000000000000..cb4655c86eba --- /dev/null +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_browser_service.py @@ -0,0 +1,2231 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account + +from google.ads.admanager_v1.services.browser_service import ( + BrowserServiceClient, + pagers, + transports, +) +from google.ads.admanager_v1.types import browser_messages, browser_service + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert BrowserServiceClient._get_default_mtls_endpoint(None) is None + assert ( + BrowserServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + BrowserServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + BrowserServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + BrowserServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + BrowserServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + ) + + +def test__read_environment_variables(): + assert BrowserServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert BrowserServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert BrowserServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + BrowserServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert BrowserServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert BrowserServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert BrowserServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + BrowserServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert BrowserServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert BrowserServiceClient._get_client_cert_source(None, False) is None + assert ( + BrowserServiceClient._get_client_cert_source(mock_provided_cert_source, False) + is None + ) + assert ( + BrowserServiceClient._get_client_cert_source(mock_provided_cert_source, True) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + BrowserServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + BrowserServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + BrowserServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(BrowserServiceClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = BrowserServiceClient._DEFAULT_UNIVERSE + default_endpoint = BrowserServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = BrowserServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + BrowserServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + BrowserServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == BrowserServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + BrowserServiceClient._get_api_endpoint(None, None, default_universe, "auto") + == default_endpoint + ) + assert ( + BrowserServiceClient._get_api_endpoint(None, None, default_universe, "always") + == BrowserServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + BrowserServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == BrowserServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + BrowserServiceClient._get_api_endpoint(None, None, mock_universe, "never") + == mock_endpoint + ) + assert ( + BrowserServiceClient._get_api_endpoint(None, None, default_universe, "never") + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + BrowserServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + BrowserServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + BrowserServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + BrowserServiceClient._get_universe_domain(None, None) + == BrowserServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + BrowserServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = BrowserServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = BrowserServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (BrowserServiceClient, "rest"), + ], +) +def test_browser_service_client_from_service_account_info(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.BrowserServiceRestTransport, "rest"), + ], +) +def test_browser_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (BrowserServiceClient, "rest"), + ], +) +def test_browser_service_client_from_service_account_file(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +def test_browser_service_client_get_transport_class(): + transport = BrowserServiceClient.get_transport_class() + available_transports = [ + transports.BrowserServiceRestTransport, + ] + assert transport in available_transports + + transport = BrowserServiceClient.get_transport_class("rest") + assert transport == transports.BrowserServiceRestTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (BrowserServiceClient, transports.BrowserServiceRestTransport, "rest"), + ], +) +@mock.patch.object( + BrowserServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(BrowserServiceClient), +) +def test_browser_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(BrowserServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(BrowserServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + (BrowserServiceClient, transports.BrowserServiceRestTransport, "rest", "true"), + (BrowserServiceClient, transports.BrowserServiceRestTransport, "rest", "false"), + ], +) +@mock.patch.object( + BrowserServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(BrowserServiceClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_browser_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [BrowserServiceClient]) +@mock.patch.object( + BrowserServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(BrowserServiceClient), +) +def test_browser_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize("client_class", [BrowserServiceClient]) +@mock.patch.object( + BrowserServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(BrowserServiceClient), +) +def test_browser_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = BrowserServiceClient._DEFAULT_UNIVERSE + default_endpoint = BrowserServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = BrowserServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (BrowserServiceClient, transports.BrowserServiceRestTransport, "rest"), + ], +) +def test_browser_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + (BrowserServiceClient, transports.BrowserServiceRestTransport, "rest", None), + ], +) +def test_browser_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_get_browser_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_browser in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_browser] = mock_rpc + + request = {} + client.get_browser(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_browser(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_browser_rest_required_fields( + request_type=browser_service.GetBrowserRequest, +): + transport_class = transports.BrowserServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_browser._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_browser._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = browser_messages.Browser() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = browser_messages.Browser.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_browser(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_browser_rest_unset_required_fields(): + transport = transports.BrowserServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_browser._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_browser_rest_flattened(): + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = browser_messages.Browser() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "networks/sample1/browsers/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = browser_messages.Browser.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_browser(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=networks/*/browsers/*}" % client.transport._host, args[1] + ) + + +def test_get_browser_rest_flattened_error(transport: str = "rest"): + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_browser( + browser_service.GetBrowserRequest(), + name="name_value", + ) + + +def test_list_browsers_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_browsers in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_browsers] = mock_rpc + + request = {} + client.list_browsers(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_browsers(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_browsers_rest_required_fields( + request_type=browser_service.ListBrowsersRequest, +): + transport_class = transports.BrowserServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_browsers._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_browsers._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + "skip", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = browser_service.ListBrowsersResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = browser_service.ListBrowsersResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_browsers(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_browsers_rest_unset_required_fields(): + transport = transports.BrowserServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_browsers._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + "skip", + ) + ) + & set(("parent",)) + ) + + +def test_list_browsers_rest_flattened(): + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = browser_service.ListBrowsersResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = browser_service.ListBrowsersResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_browsers(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/browsers" % client.transport._host, args[1] + ) + + +def test_list_browsers_rest_flattened_error(transport: str = "rest"): + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_browsers( + browser_service.ListBrowsersRequest(), + parent="parent_value", + ) + + +def test_list_browsers_rest_pager(transport: str = "rest"): + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + browser_service.ListBrowsersResponse( + browsers=[ + browser_messages.Browser(), + browser_messages.Browser(), + browser_messages.Browser(), + ], + next_page_token="abc", + ), + browser_service.ListBrowsersResponse( + browsers=[], + next_page_token="def", + ), + browser_service.ListBrowsersResponse( + browsers=[ + browser_messages.Browser(), + ], + next_page_token="ghi", + ), + browser_service.ListBrowsersResponse( + browsers=[ + browser_messages.Browser(), + browser_messages.Browser(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + browser_service.ListBrowsersResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "networks/sample1"} + + pager = client.list_browsers(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, browser_messages.Browser) for i in results) + + pages = list(client.list_browsers(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.BrowserServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.BrowserServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = BrowserServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.BrowserServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = BrowserServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = BrowserServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.BrowserServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = BrowserServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.BrowserServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = BrowserServiceClient(transport=transport) + assert client.transport is transport + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.BrowserServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_rest(): + transport = BrowserServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_browser_rest_bad_request(request_type=browser_service.GetBrowserRequest): + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/browsers/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_browser(request) + + +@pytest.mark.parametrize( + "request_type", + [ + browser_service.GetBrowserRequest, + dict, + ], +) +def test_get_browser_rest_call_success(request_type): + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/browsers/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = browser_messages.Browser( + name="name_value", + display_name="display_name_value", + major_version="major_version_value", + minor_version="minor_version_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = browser_messages.Browser.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_browser(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, browser_messages.Browser) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.major_version == "major_version_value" + assert response.minor_version == "minor_version_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_browser_rest_interceptors(null_interceptor): + transport = transports.BrowserServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.BrowserServiceRestInterceptor(), + ) + client = BrowserServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.BrowserServiceRestInterceptor, "post_get_browser" + ) as post, mock.patch.object( + transports.BrowserServiceRestInterceptor, "post_get_browser_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.BrowserServiceRestInterceptor, "pre_get_browser" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = browser_service.GetBrowserRequest.pb( + browser_service.GetBrowserRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = browser_messages.Browser.to_json(browser_messages.Browser()) + req.return_value.content = return_value + + request = browser_service.GetBrowserRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = browser_messages.Browser() + post_with_metadata.return_value = browser_messages.Browser(), metadata + + client.get_browser( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_browsers_rest_bad_request( + request_type=browser_service.ListBrowsersRequest, +): + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_browsers(request) + + +@pytest.mark.parametrize( + "request_type", + [ + browser_service.ListBrowsersRequest, + dict, + ], +) +def test_list_browsers_rest_call_success(request_type): + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = browser_service.ListBrowsersResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = browser_service.ListBrowsersResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_browsers(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListBrowsersPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_browsers_rest_interceptors(null_interceptor): + transport = transports.BrowserServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.BrowserServiceRestInterceptor(), + ) + client = BrowserServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.BrowserServiceRestInterceptor, "post_list_browsers" + ) as post, mock.patch.object( + transports.BrowserServiceRestInterceptor, "post_list_browsers_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.BrowserServiceRestInterceptor, "pre_list_browsers" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = browser_service.ListBrowsersRequest.pb( + browser_service.ListBrowsersRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = browser_service.ListBrowsersResponse.to_json( + browser_service.ListBrowsersResponse() + ) + req.return_value.content = return_value + + request = browser_service.ListBrowsersRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = browser_service.ListBrowsersResponse() + post_with_metadata.return_value = ( + browser_service.ListBrowsersResponse(), + metadata, + ) + + client.list_browsers( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "networks/sample1/operations/reports/runs/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "networks/sample1/operations/reports/runs/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_initialize_client_w_rest(): + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_browser_empty_call_rest(): + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_browser), "__call__") as call: + client.get_browser(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = browser_service.GetBrowserRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_browsers_empty_call_rest(): + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_browsers), "__call__") as call: + client.list_browsers(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = browser_service.ListBrowsersRequest() + + assert args[0] == request_msg + + +def test_browser_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.BrowserServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_browser_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.ads.admanager_v1.services.browser_service.transports.BrowserServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.BrowserServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "get_browser", + "list_browsers", + "get_operation", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_browser_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.ads.admanager_v1.services.browser_service.transports.BrowserServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.BrowserServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id="octopus", + ) + + +def test_browser_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.ads.admanager_v1.services.browser_service.transports.BrowserServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.BrowserServiceTransport() + adc.assert_called_once() + + +def test_browser_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + BrowserServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id=None, + ) + + +def test_browser_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.BrowserServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_browser_service_host_no_port(transport_name): + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_browser_service_host_with_port(transport_name): + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_browser_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = BrowserServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = BrowserServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.get_browser._session + session2 = client2.transport.get_browser._session + assert session1 != session2 + session1 = client1.transport.list_browsers._session + session2 = client2.transport.list_browsers._session + assert session1 != session2 + + +def test_browser_path(): + network_code = "squid" + browser = "clam" + expected = "networks/{network_code}/browsers/{browser}".format( + network_code=network_code, + browser=browser, + ) + actual = BrowserServiceClient.browser_path(network_code, browser) + assert expected == actual + + +def test_parse_browser_path(): + expected = { + "network_code": "whelk", + "browser": "octopus", + } + path = BrowserServiceClient.browser_path(**expected) + + # Check that the path construction is reversible. + actual = BrowserServiceClient.parse_browser_path(path) + assert expected == actual + + +def test_network_path(): + network_code = "oyster" + expected = "networks/{network_code}".format( + network_code=network_code, + ) + actual = BrowserServiceClient.network_path(network_code) + assert expected == actual + + +def test_parse_network_path(): + expected = { + "network_code": "nudibranch", + } + path = BrowserServiceClient.network_path(**expected) + + # Check that the path construction is reversible. + actual = BrowserServiceClient.parse_network_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = BrowserServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = BrowserServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = BrowserServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = BrowserServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = BrowserServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = BrowserServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = BrowserServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = BrowserServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = BrowserServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format( + project=project, + ) + actual = BrowserServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = BrowserServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = BrowserServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = BrowserServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = BrowserServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = BrowserServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.BrowserServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.BrowserServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = BrowserServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_rest(): + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + ] + for transport in transports: + client = BrowserServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (BrowserServiceClient, transports.BrowserServiceRestTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_cms_metadata_key_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_cms_metadata_key_service.py new file mode 100644 index 000000000000..62b9182952bc --- /dev/null +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_cms_metadata_key_service.py @@ -0,0 +1,2317 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account + +from google.ads.admanager_v1.services.cms_metadata_key_service import ( + CmsMetadataKeyServiceClient, + pagers, + transports, +) +from google.ads.admanager_v1.types import ( + cms_metadata_key_enums, + cms_metadata_key_messages, + cms_metadata_key_service, +) + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert CmsMetadataKeyServiceClient._get_default_mtls_endpoint(None) is None + assert ( + CmsMetadataKeyServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + CmsMetadataKeyServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + CmsMetadataKeyServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + CmsMetadataKeyServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + CmsMetadataKeyServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +def test__read_environment_variables(): + assert CmsMetadataKeyServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert CmsMetadataKeyServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert CmsMetadataKeyServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + CmsMetadataKeyServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert CmsMetadataKeyServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert CmsMetadataKeyServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert CmsMetadataKeyServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + CmsMetadataKeyServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert CmsMetadataKeyServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert CmsMetadataKeyServiceClient._get_client_cert_source(None, False) is None + assert ( + CmsMetadataKeyServiceClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + CmsMetadataKeyServiceClient._get_client_cert_source( + mock_provided_cert_source, True + ) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + CmsMetadataKeyServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + CmsMetadataKeyServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + CmsMetadataKeyServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(CmsMetadataKeyServiceClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = CmsMetadataKeyServiceClient._DEFAULT_UNIVERSE + default_endpoint = CmsMetadataKeyServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = CmsMetadataKeyServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + CmsMetadataKeyServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + CmsMetadataKeyServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == CmsMetadataKeyServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + CmsMetadataKeyServiceClient._get_api_endpoint( + None, None, default_universe, "auto" + ) + == default_endpoint + ) + assert ( + CmsMetadataKeyServiceClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == CmsMetadataKeyServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + CmsMetadataKeyServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == CmsMetadataKeyServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + CmsMetadataKeyServiceClient._get_api_endpoint( + None, None, mock_universe, "never" + ) + == mock_endpoint + ) + assert ( + CmsMetadataKeyServiceClient._get_api_endpoint( + None, None, default_universe, "never" + ) + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + CmsMetadataKeyServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + CmsMetadataKeyServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + CmsMetadataKeyServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + CmsMetadataKeyServiceClient._get_universe_domain(None, None) + == CmsMetadataKeyServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + CmsMetadataKeyServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = CmsMetadataKeyServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = CmsMetadataKeyServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (CmsMetadataKeyServiceClient, "rest"), + ], +) +def test_cms_metadata_key_service_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.CmsMetadataKeyServiceRestTransport, "rest"), + ], +) +def test_cms_metadata_key_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (CmsMetadataKeyServiceClient, "rest"), + ], +) +def test_cms_metadata_key_service_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +def test_cms_metadata_key_service_client_get_transport_class(): + transport = CmsMetadataKeyServiceClient.get_transport_class() + available_transports = [ + transports.CmsMetadataKeyServiceRestTransport, + ] + assert transport in available_transports + + transport = CmsMetadataKeyServiceClient.get_transport_class("rest") + assert transport == transports.CmsMetadataKeyServiceRestTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + CmsMetadataKeyServiceClient, + transports.CmsMetadataKeyServiceRestTransport, + "rest", + ), + ], +) +@mock.patch.object( + CmsMetadataKeyServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(CmsMetadataKeyServiceClient), +) +def test_cms_metadata_key_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(CmsMetadataKeyServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(CmsMetadataKeyServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + CmsMetadataKeyServiceClient, + transports.CmsMetadataKeyServiceRestTransport, + "rest", + "true", + ), + ( + CmsMetadataKeyServiceClient, + transports.CmsMetadataKeyServiceRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + CmsMetadataKeyServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(CmsMetadataKeyServiceClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_cms_metadata_key_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [CmsMetadataKeyServiceClient]) +@mock.patch.object( + CmsMetadataKeyServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(CmsMetadataKeyServiceClient), +) +def test_cms_metadata_key_service_client_get_mtls_endpoint_and_cert_source( + client_class, +): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize("client_class", [CmsMetadataKeyServiceClient]) +@mock.patch.object( + CmsMetadataKeyServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(CmsMetadataKeyServiceClient), +) +def test_cms_metadata_key_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = CmsMetadataKeyServiceClient._DEFAULT_UNIVERSE + default_endpoint = CmsMetadataKeyServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = CmsMetadataKeyServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + CmsMetadataKeyServiceClient, + transports.CmsMetadataKeyServiceRestTransport, + "rest", + ), + ], +) +def test_cms_metadata_key_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + CmsMetadataKeyServiceClient, + transports.CmsMetadataKeyServiceRestTransport, + "rest", + None, + ), + ], +) +def test_cms_metadata_key_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_get_cms_metadata_key_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_cms_metadata_key in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_cms_metadata_key + ] = mock_rpc + + request = {} + client.get_cms_metadata_key(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_cms_metadata_key(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_cms_metadata_key_rest_required_fields( + request_type=cms_metadata_key_service.GetCmsMetadataKeyRequest, +): + transport_class = transports.CmsMetadataKeyServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_cms_metadata_key._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_cms_metadata_key._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = cms_metadata_key_messages.CmsMetadataKey() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = cms_metadata_key_messages.CmsMetadataKey.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_cms_metadata_key(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_cms_metadata_key_rest_unset_required_fields(): + transport = transports.CmsMetadataKeyServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_cms_metadata_key._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_cms_metadata_key_rest_flattened(): + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = cms_metadata_key_messages.CmsMetadataKey() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "networks/sample1/cmsMetadataKeys/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = cms_metadata_key_messages.CmsMetadataKey.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_cms_metadata_key(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=networks/*/cmsMetadataKeys/*}" % client.transport._host, + args[1], + ) + + +def test_get_cms_metadata_key_rest_flattened_error(transport: str = "rest"): + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_cms_metadata_key( + cms_metadata_key_service.GetCmsMetadataKeyRequest(), + name="name_value", + ) + + +def test_list_cms_metadata_keys_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_cms_metadata_keys + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_cms_metadata_keys + ] = mock_rpc + + request = {} + client.list_cms_metadata_keys(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_cms_metadata_keys(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_cms_metadata_keys_rest_required_fields( + request_type=cms_metadata_key_service.ListCmsMetadataKeysRequest, +): + transport_class = transports.CmsMetadataKeyServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_cms_metadata_keys._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_cms_metadata_keys._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + "skip", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = cms_metadata_key_service.ListCmsMetadataKeysResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = cms_metadata_key_service.ListCmsMetadataKeysResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_cms_metadata_keys(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_cms_metadata_keys_rest_unset_required_fields(): + transport = transports.CmsMetadataKeyServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_cms_metadata_keys._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + "skip", + ) + ) + & set(("parent",)) + ) + + +def test_list_cms_metadata_keys_rest_flattened(): + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = cms_metadata_key_service.ListCmsMetadataKeysResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = cms_metadata_key_service.ListCmsMetadataKeysResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_cms_metadata_keys(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/cmsMetadataKeys" % client.transport._host, + args[1], + ) + + +def test_list_cms_metadata_keys_rest_flattened_error(transport: str = "rest"): + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_cms_metadata_keys( + cms_metadata_key_service.ListCmsMetadataKeysRequest(), + parent="parent_value", + ) + + +def test_list_cms_metadata_keys_rest_pager(transport: str = "rest"): + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + cms_metadata_key_service.ListCmsMetadataKeysResponse( + cms_metadata_keys=[ + cms_metadata_key_messages.CmsMetadataKey(), + cms_metadata_key_messages.CmsMetadataKey(), + cms_metadata_key_messages.CmsMetadataKey(), + ], + next_page_token="abc", + ), + cms_metadata_key_service.ListCmsMetadataKeysResponse( + cms_metadata_keys=[], + next_page_token="def", + ), + cms_metadata_key_service.ListCmsMetadataKeysResponse( + cms_metadata_keys=[ + cms_metadata_key_messages.CmsMetadataKey(), + ], + next_page_token="ghi", + ), + cms_metadata_key_service.ListCmsMetadataKeysResponse( + cms_metadata_keys=[ + cms_metadata_key_messages.CmsMetadataKey(), + cms_metadata_key_messages.CmsMetadataKey(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + cms_metadata_key_service.ListCmsMetadataKeysResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "networks/sample1"} + + pager = client.list_cms_metadata_keys(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, cms_metadata_key_messages.CmsMetadataKey) for i in results + ) + + pages = list(client.list_cms_metadata_keys(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.CmsMetadataKeyServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.CmsMetadataKeyServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CmsMetadataKeyServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.CmsMetadataKeyServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CmsMetadataKeyServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CmsMetadataKeyServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.CmsMetadataKeyServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CmsMetadataKeyServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.CmsMetadataKeyServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = CmsMetadataKeyServiceClient(transport=transport) + assert client.transport is transport + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CmsMetadataKeyServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_rest(): + transport = CmsMetadataKeyServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_cms_metadata_key_rest_bad_request( + request_type=cms_metadata_key_service.GetCmsMetadataKeyRequest, +): + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/cmsMetadataKeys/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_cms_metadata_key(request) + + +@pytest.mark.parametrize( + "request_type", + [ + cms_metadata_key_service.GetCmsMetadataKeyRequest, + dict, + ], +) +def test_get_cms_metadata_key_rest_call_success(request_type): + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/cmsMetadataKeys/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = cms_metadata_key_messages.CmsMetadataKey( + name="name_value", + display_name="display_name_value", + status=cms_metadata_key_enums.CmsMetadataKeyStatusEnum.CmsMetadataKeyStatus.ACTIVE, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = cms_metadata_key_messages.CmsMetadataKey.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_cms_metadata_key(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, cms_metadata_key_messages.CmsMetadataKey) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert ( + response.status + == cms_metadata_key_enums.CmsMetadataKeyStatusEnum.CmsMetadataKeyStatus.ACTIVE + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_cms_metadata_key_rest_interceptors(null_interceptor): + transport = transports.CmsMetadataKeyServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.CmsMetadataKeyServiceRestInterceptor(), + ) + client = CmsMetadataKeyServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.CmsMetadataKeyServiceRestInterceptor, "post_get_cms_metadata_key" + ) as post, mock.patch.object( + transports.CmsMetadataKeyServiceRestInterceptor, + "post_get_cms_metadata_key_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.CmsMetadataKeyServiceRestInterceptor, "pre_get_cms_metadata_key" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = cms_metadata_key_service.GetCmsMetadataKeyRequest.pb( + cms_metadata_key_service.GetCmsMetadataKeyRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = cms_metadata_key_messages.CmsMetadataKey.to_json( + cms_metadata_key_messages.CmsMetadataKey() + ) + req.return_value.content = return_value + + request = cms_metadata_key_service.GetCmsMetadataKeyRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = cms_metadata_key_messages.CmsMetadataKey() + post_with_metadata.return_value = ( + cms_metadata_key_messages.CmsMetadataKey(), + metadata, + ) + + client.get_cms_metadata_key( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_cms_metadata_keys_rest_bad_request( + request_type=cms_metadata_key_service.ListCmsMetadataKeysRequest, +): + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_cms_metadata_keys(request) + + +@pytest.mark.parametrize( + "request_type", + [ + cms_metadata_key_service.ListCmsMetadataKeysRequest, + dict, + ], +) +def test_list_cms_metadata_keys_rest_call_success(request_type): + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = cms_metadata_key_service.ListCmsMetadataKeysResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = cms_metadata_key_service.ListCmsMetadataKeysResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_cms_metadata_keys(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListCmsMetadataKeysPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_cms_metadata_keys_rest_interceptors(null_interceptor): + transport = transports.CmsMetadataKeyServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.CmsMetadataKeyServiceRestInterceptor(), + ) + client = CmsMetadataKeyServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.CmsMetadataKeyServiceRestInterceptor, "post_list_cms_metadata_keys" + ) as post, mock.patch.object( + transports.CmsMetadataKeyServiceRestInterceptor, + "post_list_cms_metadata_keys_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.CmsMetadataKeyServiceRestInterceptor, "pre_list_cms_metadata_keys" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = cms_metadata_key_service.ListCmsMetadataKeysRequest.pb( + cms_metadata_key_service.ListCmsMetadataKeysRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = cms_metadata_key_service.ListCmsMetadataKeysResponse.to_json( + cms_metadata_key_service.ListCmsMetadataKeysResponse() + ) + req.return_value.content = return_value + + request = cms_metadata_key_service.ListCmsMetadataKeysRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = cms_metadata_key_service.ListCmsMetadataKeysResponse() + post_with_metadata.return_value = ( + cms_metadata_key_service.ListCmsMetadataKeysResponse(), + metadata, + ) + + client.list_cms_metadata_keys( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "networks/sample1/operations/reports/runs/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "networks/sample1/operations/reports/runs/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_initialize_client_w_rest(): + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_cms_metadata_key_empty_call_rest(): + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_cms_metadata_key), "__call__" + ) as call: + client.get_cms_metadata_key(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = cms_metadata_key_service.GetCmsMetadataKeyRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_cms_metadata_keys_empty_call_rest(): + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_cms_metadata_keys), "__call__" + ) as call: + client.list_cms_metadata_keys(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = cms_metadata_key_service.ListCmsMetadataKeysRequest() + + assert args[0] == request_msg + + +def test_cms_metadata_key_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.CmsMetadataKeyServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_cms_metadata_key_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.ads.admanager_v1.services.cms_metadata_key_service.transports.CmsMetadataKeyServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.CmsMetadataKeyServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "get_cms_metadata_key", + "list_cms_metadata_keys", + "get_operation", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_cms_metadata_key_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.ads.admanager_v1.services.cms_metadata_key_service.transports.CmsMetadataKeyServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CmsMetadataKeyServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id="octopus", + ) + + +def test_cms_metadata_key_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.ads.admanager_v1.services.cms_metadata_key_service.transports.CmsMetadataKeyServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CmsMetadataKeyServiceTransport() + adc.assert_called_once() + + +def test_cms_metadata_key_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + CmsMetadataKeyServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id=None, + ) + + +def test_cms_metadata_key_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.CmsMetadataKeyServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_cms_metadata_key_service_host_no_port(transport_name): + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_cms_metadata_key_service_host_with_port(transport_name): + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_cms_metadata_key_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = CmsMetadataKeyServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = CmsMetadataKeyServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.get_cms_metadata_key._session + session2 = client2.transport.get_cms_metadata_key._session + assert session1 != session2 + session1 = client1.transport.list_cms_metadata_keys._session + session2 = client2.transport.list_cms_metadata_keys._session + assert session1 != session2 + + +def test_cms_metadata_key_path(): + network_code = "squid" + cms_metadata_key = "clam" + expected = "networks/{network_code}/cmsMetadataKeys/{cms_metadata_key}".format( + network_code=network_code, + cms_metadata_key=cms_metadata_key, + ) + actual = CmsMetadataKeyServiceClient.cms_metadata_key_path( + network_code, cms_metadata_key + ) + assert expected == actual + + +def test_parse_cms_metadata_key_path(): + expected = { + "network_code": "whelk", + "cms_metadata_key": "octopus", + } + path = CmsMetadataKeyServiceClient.cms_metadata_key_path(**expected) + + # Check that the path construction is reversible. + actual = CmsMetadataKeyServiceClient.parse_cms_metadata_key_path(path) + assert expected == actual + + +def test_network_path(): + network_code = "oyster" + expected = "networks/{network_code}".format( + network_code=network_code, + ) + actual = CmsMetadataKeyServiceClient.network_path(network_code) + assert expected == actual + + +def test_parse_network_path(): + expected = { + "network_code": "nudibranch", + } + path = CmsMetadataKeyServiceClient.network_path(**expected) + + # Check that the path construction is reversible. + actual = CmsMetadataKeyServiceClient.parse_network_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = CmsMetadataKeyServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = CmsMetadataKeyServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = CmsMetadataKeyServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = CmsMetadataKeyServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = CmsMetadataKeyServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = CmsMetadataKeyServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = CmsMetadataKeyServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = CmsMetadataKeyServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = CmsMetadataKeyServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format( + project=project, + ) + actual = CmsMetadataKeyServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = CmsMetadataKeyServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = CmsMetadataKeyServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = CmsMetadataKeyServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = CmsMetadataKeyServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = CmsMetadataKeyServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.CmsMetadataKeyServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.CmsMetadataKeyServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = CmsMetadataKeyServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_rest(): + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + ] + for transport in transports: + client = CmsMetadataKeyServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (CmsMetadataKeyServiceClient, transports.CmsMetadataKeyServiceRestTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_cms_metadata_value_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_cms_metadata_value_service.py new file mode 100644 index 000000000000..988ff854c176 --- /dev/null +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_cms_metadata_value_service.py @@ -0,0 +1,2350 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account + +from google.ads.admanager_v1.services.cms_metadata_value_service import ( + CmsMetadataValueServiceClient, + pagers, + transports, +) +from google.ads.admanager_v1.types import ( + cms_metadata_value_enums, + cms_metadata_value_messages, + cms_metadata_value_service, +) + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert CmsMetadataValueServiceClient._get_default_mtls_endpoint(None) is None + assert ( + CmsMetadataValueServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + CmsMetadataValueServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + CmsMetadataValueServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + CmsMetadataValueServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + CmsMetadataValueServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +def test__read_environment_variables(): + assert CmsMetadataValueServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert CmsMetadataValueServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert CmsMetadataValueServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + CmsMetadataValueServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert CmsMetadataValueServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert CmsMetadataValueServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert CmsMetadataValueServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + CmsMetadataValueServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert CmsMetadataValueServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert CmsMetadataValueServiceClient._get_client_cert_source(None, False) is None + assert ( + CmsMetadataValueServiceClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + CmsMetadataValueServiceClient._get_client_cert_source( + mock_provided_cert_source, True + ) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + CmsMetadataValueServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + CmsMetadataValueServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + CmsMetadataValueServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(CmsMetadataValueServiceClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = CmsMetadataValueServiceClient._DEFAULT_UNIVERSE + default_endpoint = CmsMetadataValueServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = CmsMetadataValueServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + CmsMetadataValueServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + CmsMetadataValueServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == CmsMetadataValueServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + CmsMetadataValueServiceClient._get_api_endpoint( + None, None, default_universe, "auto" + ) + == default_endpoint + ) + assert ( + CmsMetadataValueServiceClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == CmsMetadataValueServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + CmsMetadataValueServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == CmsMetadataValueServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + CmsMetadataValueServiceClient._get_api_endpoint( + None, None, mock_universe, "never" + ) + == mock_endpoint + ) + assert ( + CmsMetadataValueServiceClient._get_api_endpoint( + None, None, default_universe, "never" + ) + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + CmsMetadataValueServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + CmsMetadataValueServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + CmsMetadataValueServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + CmsMetadataValueServiceClient._get_universe_domain(None, None) + == CmsMetadataValueServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + CmsMetadataValueServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = CmsMetadataValueServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = CmsMetadataValueServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (CmsMetadataValueServiceClient, "rest"), + ], +) +def test_cms_metadata_value_service_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.CmsMetadataValueServiceRestTransport, "rest"), + ], +) +def test_cms_metadata_value_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (CmsMetadataValueServiceClient, "rest"), + ], +) +def test_cms_metadata_value_service_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +def test_cms_metadata_value_service_client_get_transport_class(): + transport = CmsMetadataValueServiceClient.get_transport_class() + available_transports = [ + transports.CmsMetadataValueServiceRestTransport, + ] + assert transport in available_transports + + transport = CmsMetadataValueServiceClient.get_transport_class("rest") + assert transport == transports.CmsMetadataValueServiceRestTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + CmsMetadataValueServiceClient, + transports.CmsMetadataValueServiceRestTransport, + "rest", + ), + ], +) +@mock.patch.object( + CmsMetadataValueServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(CmsMetadataValueServiceClient), +) +def test_cms_metadata_value_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(CmsMetadataValueServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(CmsMetadataValueServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + CmsMetadataValueServiceClient, + transports.CmsMetadataValueServiceRestTransport, + "rest", + "true", + ), + ( + CmsMetadataValueServiceClient, + transports.CmsMetadataValueServiceRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + CmsMetadataValueServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(CmsMetadataValueServiceClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_cms_metadata_value_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [CmsMetadataValueServiceClient]) +@mock.patch.object( + CmsMetadataValueServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(CmsMetadataValueServiceClient), +) +def test_cms_metadata_value_service_client_get_mtls_endpoint_and_cert_source( + client_class, +): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize("client_class", [CmsMetadataValueServiceClient]) +@mock.patch.object( + CmsMetadataValueServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(CmsMetadataValueServiceClient), +) +def test_cms_metadata_value_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = CmsMetadataValueServiceClient._DEFAULT_UNIVERSE + default_endpoint = CmsMetadataValueServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = CmsMetadataValueServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + CmsMetadataValueServiceClient, + transports.CmsMetadataValueServiceRestTransport, + "rest", + ), + ], +) +def test_cms_metadata_value_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + CmsMetadataValueServiceClient, + transports.CmsMetadataValueServiceRestTransport, + "rest", + None, + ), + ], +) +def test_cms_metadata_value_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_get_cms_metadata_value_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_cms_metadata_value + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_cms_metadata_value + ] = mock_rpc + + request = {} + client.get_cms_metadata_value(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_cms_metadata_value(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_cms_metadata_value_rest_required_fields( + request_type=cms_metadata_value_service.GetCmsMetadataValueRequest, +): + transport_class = transports.CmsMetadataValueServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_cms_metadata_value._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_cms_metadata_value._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = cms_metadata_value_messages.CmsMetadataValue() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = cms_metadata_value_messages.CmsMetadataValue.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_cms_metadata_value(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_cms_metadata_value_rest_unset_required_fields(): + transport = transports.CmsMetadataValueServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_cms_metadata_value._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_cms_metadata_value_rest_flattened(): + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = cms_metadata_value_messages.CmsMetadataValue() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "networks/sample1/cmsMetadataValues/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = cms_metadata_value_messages.CmsMetadataValue.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_cms_metadata_value(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=networks/*/cmsMetadataValues/*}" % client.transport._host, + args[1], + ) + + +def test_get_cms_metadata_value_rest_flattened_error(transport: str = "rest"): + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_cms_metadata_value( + cms_metadata_value_service.GetCmsMetadataValueRequest(), + name="name_value", + ) + + +def test_list_cms_metadata_values_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_cms_metadata_values + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_cms_metadata_values + ] = mock_rpc + + request = {} + client.list_cms_metadata_values(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_cms_metadata_values(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_cms_metadata_values_rest_required_fields( + request_type=cms_metadata_value_service.ListCmsMetadataValuesRequest, +): + transport_class = transports.CmsMetadataValueServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_cms_metadata_values._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_cms_metadata_values._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + "skip", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = cms_metadata_value_service.ListCmsMetadataValuesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = cms_metadata_value_service.ListCmsMetadataValuesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_cms_metadata_values(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_cms_metadata_values_rest_unset_required_fields(): + transport = transports.CmsMetadataValueServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_cms_metadata_values._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + "skip", + ) + ) + & set(("parent",)) + ) + + +def test_list_cms_metadata_values_rest_flattened(): + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = cms_metadata_value_service.ListCmsMetadataValuesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = cms_metadata_value_service.ListCmsMetadataValuesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_cms_metadata_values(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/cmsMetadataValues" % client.transport._host, + args[1], + ) + + +def test_list_cms_metadata_values_rest_flattened_error(transport: str = "rest"): + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_cms_metadata_values( + cms_metadata_value_service.ListCmsMetadataValuesRequest(), + parent="parent_value", + ) + + +def test_list_cms_metadata_values_rest_pager(transport: str = "rest"): + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + cms_metadata_value_service.ListCmsMetadataValuesResponse( + cms_metadata_values=[ + cms_metadata_value_messages.CmsMetadataValue(), + cms_metadata_value_messages.CmsMetadataValue(), + cms_metadata_value_messages.CmsMetadataValue(), + ], + next_page_token="abc", + ), + cms_metadata_value_service.ListCmsMetadataValuesResponse( + cms_metadata_values=[], + next_page_token="def", + ), + cms_metadata_value_service.ListCmsMetadataValuesResponse( + cms_metadata_values=[ + cms_metadata_value_messages.CmsMetadataValue(), + ], + next_page_token="ghi", + ), + cms_metadata_value_service.ListCmsMetadataValuesResponse( + cms_metadata_values=[ + cms_metadata_value_messages.CmsMetadataValue(), + cms_metadata_value_messages.CmsMetadataValue(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + cms_metadata_value_service.ListCmsMetadataValuesResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "networks/sample1"} + + pager = client.list_cms_metadata_values(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, cms_metadata_value_messages.CmsMetadataValue) for i in results + ) + + pages = list(client.list_cms_metadata_values(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.CmsMetadataValueServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.CmsMetadataValueServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CmsMetadataValueServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.CmsMetadataValueServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CmsMetadataValueServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CmsMetadataValueServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.CmsMetadataValueServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CmsMetadataValueServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.CmsMetadataValueServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = CmsMetadataValueServiceClient(transport=transport) + assert client.transport is transport + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CmsMetadataValueServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_rest(): + transport = CmsMetadataValueServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_cms_metadata_value_rest_bad_request( + request_type=cms_metadata_value_service.GetCmsMetadataValueRequest, +): + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/cmsMetadataValues/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_cms_metadata_value(request) + + +@pytest.mark.parametrize( + "request_type", + [ + cms_metadata_value_service.GetCmsMetadataValueRequest, + dict, + ], +) +def test_get_cms_metadata_value_rest_call_success(request_type): + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/cmsMetadataValues/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = cms_metadata_value_messages.CmsMetadataValue( + name="name_value", + display_name="display_name_value", + key="key_value", + status=cms_metadata_value_enums.CmsMetadataValueStatusEnum.CmsMetadataValueStatus.ACTIVE, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = cms_metadata_value_messages.CmsMetadataValue.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_cms_metadata_value(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, cms_metadata_value_messages.CmsMetadataValue) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.key == "key_value" + assert ( + response.status + == cms_metadata_value_enums.CmsMetadataValueStatusEnum.CmsMetadataValueStatus.ACTIVE + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_cms_metadata_value_rest_interceptors(null_interceptor): + transport = transports.CmsMetadataValueServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.CmsMetadataValueServiceRestInterceptor(), + ) + client = CmsMetadataValueServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.CmsMetadataValueServiceRestInterceptor, "post_get_cms_metadata_value" + ) as post, mock.patch.object( + transports.CmsMetadataValueServiceRestInterceptor, + "post_get_cms_metadata_value_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.CmsMetadataValueServiceRestInterceptor, "pre_get_cms_metadata_value" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = cms_metadata_value_service.GetCmsMetadataValueRequest.pb( + cms_metadata_value_service.GetCmsMetadataValueRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = cms_metadata_value_messages.CmsMetadataValue.to_json( + cms_metadata_value_messages.CmsMetadataValue() + ) + req.return_value.content = return_value + + request = cms_metadata_value_service.GetCmsMetadataValueRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = cms_metadata_value_messages.CmsMetadataValue() + post_with_metadata.return_value = ( + cms_metadata_value_messages.CmsMetadataValue(), + metadata, + ) + + client.get_cms_metadata_value( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_cms_metadata_values_rest_bad_request( + request_type=cms_metadata_value_service.ListCmsMetadataValuesRequest, +): + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_cms_metadata_values(request) + + +@pytest.mark.parametrize( + "request_type", + [ + cms_metadata_value_service.ListCmsMetadataValuesRequest, + dict, + ], +) +def test_list_cms_metadata_values_rest_call_success(request_type): + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = cms_metadata_value_service.ListCmsMetadataValuesResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = cms_metadata_value_service.ListCmsMetadataValuesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_cms_metadata_values(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListCmsMetadataValuesPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_cms_metadata_values_rest_interceptors(null_interceptor): + transport = transports.CmsMetadataValueServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.CmsMetadataValueServiceRestInterceptor(), + ) + client = CmsMetadataValueServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.CmsMetadataValueServiceRestInterceptor, + "post_list_cms_metadata_values", + ) as post, mock.patch.object( + transports.CmsMetadataValueServiceRestInterceptor, + "post_list_cms_metadata_values_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.CmsMetadataValueServiceRestInterceptor, + "pre_list_cms_metadata_values", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = cms_metadata_value_service.ListCmsMetadataValuesRequest.pb( + cms_metadata_value_service.ListCmsMetadataValuesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = cms_metadata_value_service.ListCmsMetadataValuesResponse.to_json( + cms_metadata_value_service.ListCmsMetadataValuesResponse() + ) + req.return_value.content = return_value + + request = cms_metadata_value_service.ListCmsMetadataValuesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = cms_metadata_value_service.ListCmsMetadataValuesResponse() + post_with_metadata.return_value = ( + cms_metadata_value_service.ListCmsMetadataValuesResponse(), + metadata, + ) + + client.list_cms_metadata_values( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "networks/sample1/operations/reports/runs/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "networks/sample1/operations/reports/runs/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_initialize_client_w_rest(): + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_cms_metadata_value_empty_call_rest(): + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_cms_metadata_value), "__call__" + ) as call: + client.get_cms_metadata_value(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = cms_metadata_value_service.GetCmsMetadataValueRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_cms_metadata_values_empty_call_rest(): + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_cms_metadata_values), "__call__" + ) as call: + client.list_cms_metadata_values(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = cms_metadata_value_service.ListCmsMetadataValuesRequest() + + assert args[0] == request_msg + + +def test_cms_metadata_value_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.CmsMetadataValueServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_cms_metadata_value_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.ads.admanager_v1.services.cms_metadata_value_service.transports.CmsMetadataValueServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.CmsMetadataValueServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "get_cms_metadata_value", + "list_cms_metadata_values", + "get_operation", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_cms_metadata_value_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.ads.admanager_v1.services.cms_metadata_value_service.transports.CmsMetadataValueServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CmsMetadataValueServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id="octopus", + ) + + +def test_cms_metadata_value_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.ads.admanager_v1.services.cms_metadata_value_service.transports.CmsMetadataValueServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CmsMetadataValueServiceTransport() + adc.assert_called_once() + + +def test_cms_metadata_value_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + CmsMetadataValueServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id=None, + ) + + +def test_cms_metadata_value_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.CmsMetadataValueServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_cms_metadata_value_service_host_no_port(transport_name): + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_cms_metadata_value_service_host_with_port(transport_name): + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_cms_metadata_value_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = CmsMetadataValueServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = CmsMetadataValueServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.get_cms_metadata_value._session + session2 = client2.transport.get_cms_metadata_value._session + assert session1 != session2 + session1 = client1.transport.list_cms_metadata_values._session + session2 = client2.transport.list_cms_metadata_values._session + assert session1 != session2 + + +def test_cms_metadata_key_path(): + network_code = "squid" + cms_metadata_key = "clam" + expected = "networks/{network_code}/cmsMetadataKeys/{cms_metadata_key}".format( + network_code=network_code, + cms_metadata_key=cms_metadata_key, + ) + actual = CmsMetadataValueServiceClient.cms_metadata_key_path( + network_code, cms_metadata_key + ) + assert expected == actual + + +def test_parse_cms_metadata_key_path(): + expected = { + "network_code": "whelk", + "cms_metadata_key": "octopus", + } + path = CmsMetadataValueServiceClient.cms_metadata_key_path(**expected) + + # Check that the path construction is reversible. + actual = CmsMetadataValueServiceClient.parse_cms_metadata_key_path(path) + assert expected == actual + + +def test_cms_metadata_value_path(): + network_code = "oyster" + cms_metadata_value = "nudibranch" + expected = "networks/{network_code}/cmsMetadataValues/{cms_metadata_value}".format( + network_code=network_code, + cms_metadata_value=cms_metadata_value, + ) + actual = CmsMetadataValueServiceClient.cms_metadata_value_path( + network_code, cms_metadata_value + ) + assert expected == actual + + +def test_parse_cms_metadata_value_path(): + expected = { + "network_code": "cuttlefish", + "cms_metadata_value": "mussel", + } + path = CmsMetadataValueServiceClient.cms_metadata_value_path(**expected) + + # Check that the path construction is reversible. + actual = CmsMetadataValueServiceClient.parse_cms_metadata_value_path(path) + assert expected == actual + + +def test_network_path(): + network_code = "winkle" + expected = "networks/{network_code}".format( + network_code=network_code, + ) + actual = CmsMetadataValueServiceClient.network_path(network_code) + assert expected == actual + + +def test_parse_network_path(): + expected = { + "network_code": "nautilus", + } + path = CmsMetadataValueServiceClient.network_path(**expected) + + # Check that the path construction is reversible. + actual = CmsMetadataValueServiceClient.parse_network_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "scallop" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = CmsMetadataValueServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "abalone", + } + path = CmsMetadataValueServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = CmsMetadataValueServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "squid" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = CmsMetadataValueServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "clam", + } + path = CmsMetadataValueServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = CmsMetadataValueServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "whelk" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = CmsMetadataValueServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "octopus", + } + path = CmsMetadataValueServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = CmsMetadataValueServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "oyster" + expected = "projects/{project}".format( + project=project, + ) + actual = CmsMetadataValueServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nudibranch", + } + path = CmsMetadataValueServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = CmsMetadataValueServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "cuttlefish" + location = "mussel" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = CmsMetadataValueServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "winkle", + "location": "nautilus", + } + path = CmsMetadataValueServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = CmsMetadataValueServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.CmsMetadataValueServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.CmsMetadataValueServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = CmsMetadataValueServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_rest(): + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + ] + for transport in transports: + client = CmsMetadataValueServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + ( + CmsMetadataValueServiceClient, + transports.CmsMetadataValueServiceRestTransport, + ), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_contact_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_contact_service.py new file mode 100644 index 000000000000..e14e8029da15 --- /dev/null +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_contact_service.py @@ -0,0 +1,3859 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore + +from google.ads.admanager_v1.services.contact_service import ( + ContactServiceClient, + pagers, + transports, +) +from google.ads.admanager_v1.types import ( + contact_enums, + contact_messages, + contact_service, +) + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert ContactServiceClient._get_default_mtls_endpoint(None) is None + assert ( + ContactServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + ContactServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + ContactServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + ContactServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + ContactServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + ) + + +def test__read_environment_variables(): + assert ContactServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert ContactServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert ContactServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + ContactServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert ContactServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert ContactServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert ContactServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + ContactServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert ContactServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert ContactServiceClient._get_client_cert_source(None, False) is None + assert ( + ContactServiceClient._get_client_cert_source(mock_provided_cert_source, False) + is None + ) + assert ( + ContactServiceClient._get_client_cert_source(mock_provided_cert_source, True) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + ContactServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + ContactServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + ContactServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ContactServiceClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = ContactServiceClient._DEFAULT_UNIVERSE + default_endpoint = ContactServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = ContactServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + ContactServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + ContactServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == ContactServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + ContactServiceClient._get_api_endpoint(None, None, default_universe, "auto") + == default_endpoint + ) + assert ( + ContactServiceClient._get_api_endpoint(None, None, default_universe, "always") + == ContactServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + ContactServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == ContactServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + ContactServiceClient._get_api_endpoint(None, None, mock_universe, "never") + == mock_endpoint + ) + assert ( + ContactServiceClient._get_api_endpoint(None, None, default_universe, "never") + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + ContactServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + ContactServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + ContactServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + ContactServiceClient._get_universe_domain(None, None) + == ContactServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + ContactServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ContactServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ContactServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (ContactServiceClient, "rest"), + ], +) +def test_contact_service_client_from_service_account_info(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.ContactServiceRestTransport, "rest"), + ], +) +def test_contact_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (ContactServiceClient, "rest"), + ], +) +def test_contact_service_client_from_service_account_file(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +def test_contact_service_client_get_transport_class(): + transport = ContactServiceClient.get_transport_class() + available_transports = [ + transports.ContactServiceRestTransport, + ] + assert transport in available_transports + + transport = ContactServiceClient.get_transport_class("rest") + assert transport == transports.ContactServiceRestTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (ContactServiceClient, transports.ContactServiceRestTransport, "rest"), + ], +) +@mock.patch.object( + ContactServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ContactServiceClient), +) +def test_contact_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(ContactServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(ContactServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + (ContactServiceClient, transports.ContactServiceRestTransport, "rest", "true"), + (ContactServiceClient, transports.ContactServiceRestTransport, "rest", "false"), + ], +) +@mock.patch.object( + ContactServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ContactServiceClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_contact_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [ContactServiceClient]) +@mock.patch.object( + ContactServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(ContactServiceClient), +) +def test_contact_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize("client_class", [ContactServiceClient]) +@mock.patch.object( + ContactServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ContactServiceClient), +) +def test_contact_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = ContactServiceClient._DEFAULT_UNIVERSE + default_endpoint = ContactServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = ContactServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (ContactServiceClient, transports.ContactServiceRestTransport, "rest"), + ], +) +def test_contact_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + (ContactServiceClient, transports.ContactServiceRestTransport, "rest", None), + ], +) +def test_contact_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_get_contact_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_contact in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_contact] = mock_rpc + + request = {} + client.get_contact(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_contact(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_contact_rest_required_fields( + request_type=contact_service.GetContactRequest, +): + transport_class = transports.ContactServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_contact._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_contact._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = contact_messages.Contact() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = contact_messages.Contact.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_contact(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_contact_rest_unset_required_fields(): + transport = transports.ContactServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_contact._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_contact_rest_flattened(): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = contact_messages.Contact() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "networks/sample1/contacts/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = contact_messages.Contact.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_contact(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=networks/*/contacts/*}" % client.transport._host, args[1] + ) + + +def test_get_contact_rest_flattened_error(transport: str = "rest"): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_contact( + contact_service.GetContactRequest(), + name="name_value", + ) + + +def test_list_contacts_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_contacts in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_contacts] = mock_rpc + + request = {} + client.list_contacts(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_contacts(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_contacts_rest_required_fields( + request_type=contact_service.ListContactsRequest, +): + transport_class = transports.ContactServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_contacts._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_contacts._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + "skip", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = contact_service.ListContactsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = contact_service.ListContactsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_contacts(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_contacts_rest_unset_required_fields(): + transport = transports.ContactServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_contacts._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + "skip", + ) + ) + & set(("parent",)) + ) + + +def test_list_contacts_rest_flattened(): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = contact_service.ListContactsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = contact_service.ListContactsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_contacts(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/contacts" % client.transport._host, args[1] + ) + + +def test_list_contacts_rest_flattened_error(transport: str = "rest"): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_contacts( + contact_service.ListContactsRequest(), + parent="parent_value", + ) + + +def test_list_contacts_rest_pager(transport: str = "rest"): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + contact_service.ListContactsResponse( + contacts=[ + contact_messages.Contact(), + contact_messages.Contact(), + contact_messages.Contact(), + ], + next_page_token="abc", + ), + contact_service.ListContactsResponse( + contacts=[], + next_page_token="def", + ), + contact_service.ListContactsResponse( + contacts=[ + contact_messages.Contact(), + ], + next_page_token="ghi", + ), + contact_service.ListContactsResponse( + contacts=[ + contact_messages.Contact(), + contact_messages.Contact(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + contact_service.ListContactsResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "networks/sample1"} + + pager = client.list_contacts(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, contact_messages.Contact) for i in results) + + pages = list(client.list_contacts(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_create_contact_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.create_contact in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.create_contact] = mock_rpc + + request = {} + client.create_contact(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.create_contact(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_contact_rest_required_fields( + request_type=contact_service.CreateContactRequest, +): + transport_class = transports.ContactServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_contact._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_contact._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = contact_messages.Contact() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = contact_messages.Contact.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.create_contact(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_create_contact_rest_unset_required_fields(): + transport = transports.ContactServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_contact._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "contact", + ) + ) + ) + + +def test_create_contact_rest_flattened(): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = contact_messages.Contact() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + contact=contact_messages.Contact(name="name_value"), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = contact_messages.Contact.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.create_contact(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/contacts" % client.transport._host, args[1] + ) + + +def test_create_contact_rest_flattened_error(transport: str = "rest"): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_contact( + contact_service.CreateContactRequest(), + parent="parent_value", + contact=contact_messages.Contact(name="name_value"), + ) + + +def test_batch_create_contacts_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_create_contacts + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_create_contacts + ] = mock_rpc + + request = {} + client.batch_create_contacts(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_create_contacts(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_create_contacts_rest_required_fields( + request_type=contact_service.BatchCreateContactsRequest, +): + transport_class = transports.ContactServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_create_contacts._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_create_contacts._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = contact_service.BatchCreateContactsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = contact_service.BatchCreateContactsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_create_contacts(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_create_contacts_rest_unset_required_fields(): + transport = transports.ContactServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_create_contacts._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "requests", + ) + ) + ) + + +def test_batch_create_contacts_rest_flattened(): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = contact_service.BatchCreateContactsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + requests=[contact_service.CreateContactRequest(parent="parent_value")], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = contact_service.BatchCreateContactsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.batch_create_contacts(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/contacts:batchCreate" % client.transport._host, + args[1], + ) + + +def test_batch_create_contacts_rest_flattened_error(transport: str = "rest"): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_create_contacts( + contact_service.BatchCreateContactsRequest(), + parent="parent_value", + requests=[contact_service.CreateContactRequest(parent="parent_value")], + ) + + +def test_update_contact_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.update_contact in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.update_contact] = mock_rpc + + request = {} + client.update_contact(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_contact(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_update_contact_rest_required_fields( + request_type=contact_service.UpdateContactRequest, +): + transport_class = transports.ContactServiceRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_contact._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_contact._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = contact_messages.Contact() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = contact_messages.Contact.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.update_contact(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_contact_rest_unset_required_fields(): + transport = transports.ContactServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_contact._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("updateMask",)) + & set( + ( + "contact", + "updateMask", + ) + ) + ) + + +def test_update_contact_rest_flattened(): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = contact_messages.Contact() + + # get arguments that satisfy an http rule for this method + sample_request = {"contact": {"name": "networks/sample1/contacts/sample2"}} + + # get truthy value for each flattened field + mock_args = dict( + contact=contact_messages.Contact(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = contact_messages.Contact.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.update_contact(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{contact.name=networks/*/contacts/*}" % client.transport._host, + args[1], + ) + + +def test_update_contact_rest_flattened_error(transport: str = "rest"): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_contact( + contact_service.UpdateContactRequest(), + contact=contact_messages.Contact(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_batch_update_contacts_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_update_contacts + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_update_contacts + ] = mock_rpc + + request = {} + client.batch_update_contacts(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_update_contacts(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_update_contacts_rest_required_fields( + request_type=contact_service.BatchUpdateContactsRequest, +): + transport_class = transports.ContactServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_update_contacts._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_update_contacts._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = contact_service.BatchUpdateContactsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = contact_service.BatchUpdateContactsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_update_contacts(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_update_contacts_rest_unset_required_fields(): + transport = transports.ContactServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_update_contacts._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "requests", + ) + ) + ) + + +def test_batch_update_contacts_rest_flattened(): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = contact_service.BatchUpdateContactsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + requests=[ + contact_service.UpdateContactRequest( + contact=contact_messages.Contact(name="name_value") + ) + ], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = contact_service.BatchUpdateContactsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.batch_update_contacts(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/contacts:batchUpdate" % client.transport._host, + args[1], + ) + + +def test_batch_update_contacts_rest_flattened_error(transport: str = "rest"): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_update_contacts( + contact_service.BatchUpdateContactsRequest(), + parent="parent_value", + requests=[ + contact_service.UpdateContactRequest( + contact=contact_messages.Contact(name="name_value") + ) + ], + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ContactServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ContactServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ContactServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ContactServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ContactServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ContactServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ContactServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ContactServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ContactServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ContactServiceClient(transport=transport) + assert client.transport is transport + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ContactServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_rest(): + transport = ContactServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_contact_rest_bad_request(request_type=contact_service.GetContactRequest): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/contacts/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_contact(request) + + +@pytest.mark.parametrize( + "request_type", + [ + contact_service.GetContactRequest, + dict, + ], +) +def test_get_contact_rest_call_success(request_type): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/contacts/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = contact_messages.Contact( + name="name_value", + display_name="display_name_value", + company="company_value", + status=contact_enums.ContactStatusEnum.ContactStatus.INVITE_CANCELED, + address="address_value", + cell_phone="cell_phone_value", + comment="comment_value", + email="email_value", + fax="fax_value", + title="title_value", + work_phone="work_phone_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = contact_messages.Contact.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_contact(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, contact_messages.Contact) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.company == "company_value" + assert ( + response.status == contact_enums.ContactStatusEnum.ContactStatus.INVITE_CANCELED + ) + assert response.address == "address_value" + assert response.cell_phone == "cell_phone_value" + assert response.comment == "comment_value" + assert response.email == "email_value" + assert response.fax == "fax_value" + assert response.title == "title_value" + assert response.work_phone == "work_phone_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_contact_rest_interceptors(null_interceptor): + transport = transports.ContactServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ContactServiceRestInterceptor(), + ) + client = ContactServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ContactServiceRestInterceptor, "post_get_contact" + ) as post, mock.patch.object( + transports.ContactServiceRestInterceptor, "post_get_contact_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.ContactServiceRestInterceptor, "pre_get_contact" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = contact_service.GetContactRequest.pb( + contact_service.GetContactRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = contact_messages.Contact.to_json(contact_messages.Contact()) + req.return_value.content = return_value + + request = contact_service.GetContactRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = contact_messages.Contact() + post_with_metadata.return_value = contact_messages.Contact(), metadata + + client.get_contact( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_contacts_rest_bad_request( + request_type=contact_service.ListContactsRequest, +): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_contacts(request) + + +@pytest.mark.parametrize( + "request_type", + [ + contact_service.ListContactsRequest, + dict, + ], +) +def test_list_contacts_rest_call_success(request_type): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = contact_service.ListContactsResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = contact_service.ListContactsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_contacts(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListContactsPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_contacts_rest_interceptors(null_interceptor): + transport = transports.ContactServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ContactServiceRestInterceptor(), + ) + client = ContactServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ContactServiceRestInterceptor, "post_list_contacts" + ) as post, mock.patch.object( + transports.ContactServiceRestInterceptor, "post_list_contacts_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.ContactServiceRestInterceptor, "pre_list_contacts" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = contact_service.ListContactsRequest.pb( + contact_service.ListContactsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = contact_service.ListContactsResponse.to_json( + contact_service.ListContactsResponse() + ) + req.return_value.content = return_value + + request = contact_service.ListContactsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = contact_service.ListContactsResponse() + post_with_metadata.return_value = ( + contact_service.ListContactsResponse(), + metadata, + ) + + client.list_contacts( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_create_contact_rest_bad_request( + request_type=contact_service.CreateContactRequest, +): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.create_contact(request) + + +@pytest.mark.parametrize( + "request_type", + [ + contact_service.CreateContactRequest, + dict, + ], +) +def test_create_contact_rest_call_success(request_type): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request_init["contact"] = { + "name": "name_value", + "display_name": "display_name_value", + "company": "company_value", + "status": 1, + "address": "address_value", + "cell_phone": "cell_phone_value", + "comment": "comment_value", + "email": "email_value", + "fax": "fax_value", + "title": "title_value", + "work_phone": "work_phone_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = contact_service.CreateContactRequest.meta.fields["contact"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["contact"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["contact"][field])): + del request_init["contact"][field][i][subfield] + else: + del request_init["contact"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = contact_messages.Contact( + name="name_value", + display_name="display_name_value", + company="company_value", + status=contact_enums.ContactStatusEnum.ContactStatus.INVITE_CANCELED, + address="address_value", + cell_phone="cell_phone_value", + comment="comment_value", + email="email_value", + fax="fax_value", + title="title_value", + work_phone="work_phone_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = contact_messages.Contact.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.create_contact(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, contact_messages.Contact) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.company == "company_value" + assert ( + response.status == contact_enums.ContactStatusEnum.ContactStatus.INVITE_CANCELED + ) + assert response.address == "address_value" + assert response.cell_phone == "cell_phone_value" + assert response.comment == "comment_value" + assert response.email == "email_value" + assert response.fax == "fax_value" + assert response.title == "title_value" + assert response.work_phone == "work_phone_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_contact_rest_interceptors(null_interceptor): + transport = transports.ContactServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ContactServiceRestInterceptor(), + ) + client = ContactServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ContactServiceRestInterceptor, "post_create_contact" + ) as post, mock.patch.object( + transports.ContactServiceRestInterceptor, "post_create_contact_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.ContactServiceRestInterceptor, "pre_create_contact" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = contact_service.CreateContactRequest.pb( + contact_service.CreateContactRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = contact_messages.Contact.to_json(contact_messages.Contact()) + req.return_value.content = return_value + + request = contact_service.CreateContactRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = contact_messages.Contact() + post_with_metadata.return_value = contact_messages.Contact(), metadata + + client.create_contact( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_batch_create_contacts_rest_bad_request( + request_type=contact_service.BatchCreateContactsRequest, +): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.batch_create_contacts(request) + + +@pytest.mark.parametrize( + "request_type", + [ + contact_service.BatchCreateContactsRequest, + dict, + ], +) +def test_batch_create_contacts_rest_call_success(request_type): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = contact_service.BatchCreateContactsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = contact_service.BatchCreateContactsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.batch_create_contacts(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, contact_service.BatchCreateContactsResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_create_contacts_rest_interceptors(null_interceptor): + transport = transports.ContactServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ContactServiceRestInterceptor(), + ) + client = ContactServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ContactServiceRestInterceptor, "post_batch_create_contacts" + ) as post, mock.patch.object( + transports.ContactServiceRestInterceptor, + "post_batch_create_contacts_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.ContactServiceRestInterceptor, "pre_batch_create_contacts" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = contact_service.BatchCreateContactsRequest.pb( + contact_service.BatchCreateContactsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = contact_service.BatchCreateContactsResponse.to_json( + contact_service.BatchCreateContactsResponse() + ) + req.return_value.content = return_value + + request = contact_service.BatchCreateContactsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = contact_service.BatchCreateContactsResponse() + post_with_metadata.return_value = ( + contact_service.BatchCreateContactsResponse(), + metadata, + ) + + client.batch_create_contacts( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_update_contact_rest_bad_request( + request_type=contact_service.UpdateContactRequest, +): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"contact": {"name": "networks/sample1/contacts/sample2"}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.update_contact(request) + + +@pytest.mark.parametrize( + "request_type", + [ + contact_service.UpdateContactRequest, + dict, + ], +) +def test_update_contact_rest_call_success(request_type): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"contact": {"name": "networks/sample1/contacts/sample2"}} + request_init["contact"] = { + "name": "networks/sample1/contacts/sample2", + "display_name": "display_name_value", + "company": "company_value", + "status": 1, + "address": "address_value", + "cell_phone": "cell_phone_value", + "comment": "comment_value", + "email": "email_value", + "fax": "fax_value", + "title": "title_value", + "work_phone": "work_phone_value", + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = contact_service.UpdateContactRequest.meta.fields["contact"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["contact"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["contact"][field])): + del request_init["contact"][field][i][subfield] + else: + del request_init["contact"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = contact_messages.Contact( + name="name_value", + display_name="display_name_value", + company="company_value", + status=contact_enums.ContactStatusEnum.ContactStatus.INVITE_CANCELED, + address="address_value", + cell_phone="cell_phone_value", + comment="comment_value", + email="email_value", + fax="fax_value", + title="title_value", + work_phone="work_phone_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = contact_messages.Contact.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.update_contact(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, contact_messages.Contact) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.company == "company_value" + assert ( + response.status == contact_enums.ContactStatusEnum.ContactStatus.INVITE_CANCELED + ) + assert response.address == "address_value" + assert response.cell_phone == "cell_phone_value" + assert response.comment == "comment_value" + assert response.email == "email_value" + assert response.fax == "fax_value" + assert response.title == "title_value" + assert response.work_phone == "work_phone_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_contact_rest_interceptors(null_interceptor): + transport = transports.ContactServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ContactServiceRestInterceptor(), + ) + client = ContactServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ContactServiceRestInterceptor, "post_update_contact" + ) as post, mock.patch.object( + transports.ContactServiceRestInterceptor, "post_update_contact_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.ContactServiceRestInterceptor, "pre_update_contact" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = contact_service.UpdateContactRequest.pb( + contact_service.UpdateContactRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = contact_messages.Contact.to_json(contact_messages.Contact()) + req.return_value.content = return_value + + request = contact_service.UpdateContactRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = contact_messages.Contact() + post_with_metadata.return_value = contact_messages.Contact(), metadata + + client.update_contact( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_batch_update_contacts_rest_bad_request( + request_type=contact_service.BatchUpdateContactsRequest, +): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.batch_update_contacts(request) + + +@pytest.mark.parametrize( + "request_type", + [ + contact_service.BatchUpdateContactsRequest, + dict, + ], +) +def test_batch_update_contacts_rest_call_success(request_type): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = contact_service.BatchUpdateContactsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = contact_service.BatchUpdateContactsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.batch_update_contacts(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, contact_service.BatchUpdateContactsResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_update_contacts_rest_interceptors(null_interceptor): + transport = transports.ContactServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ContactServiceRestInterceptor(), + ) + client = ContactServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ContactServiceRestInterceptor, "post_batch_update_contacts" + ) as post, mock.patch.object( + transports.ContactServiceRestInterceptor, + "post_batch_update_contacts_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.ContactServiceRestInterceptor, "pre_batch_update_contacts" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = contact_service.BatchUpdateContactsRequest.pb( + contact_service.BatchUpdateContactsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = contact_service.BatchUpdateContactsResponse.to_json( + contact_service.BatchUpdateContactsResponse() + ) + req.return_value.content = return_value + + request = contact_service.BatchUpdateContactsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = contact_service.BatchUpdateContactsResponse() + post_with_metadata.return_value = ( + contact_service.BatchUpdateContactsResponse(), + metadata, + ) + + client.batch_update_contacts( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "networks/sample1/operations/reports/runs/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "networks/sample1/operations/reports/runs/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_initialize_client_w_rest(): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_contact_empty_call_rest(): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_contact), "__call__") as call: + client.get_contact(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = contact_service.GetContactRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_contacts_empty_call_rest(): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_contacts), "__call__") as call: + client.list_contacts(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = contact_service.ListContactsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_contact_empty_call_rest(): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_contact), "__call__") as call: + client.create_contact(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = contact_service.CreateContactRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_create_contacts_empty_call_rest(): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_contacts), "__call__" + ) as call: + client.batch_create_contacts(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = contact_service.BatchCreateContactsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_contact_empty_call_rest(): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_contact), "__call__") as call: + client.update_contact(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = contact_service.UpdateContactRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_update_contacts_empty_call_rest(): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_update_contacts), "__call__" + ) as call: + client.batch_update_contacts(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = contact_service.BatchUpdateContactsRequest() + + assert args[0] == request_msg + + +def test_contact_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ContactServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_contact_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.ads.admanager_v1.services.contact_service.transports.ContactServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.ContactServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "get_contact", + "list_contacts", + "create_contact", + "batch_create_contacts", + "update_contact", + "batch_update_contacts", + "get_operation", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_contact_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.ads.admanager_v1.services.contact_service.transports.ContactServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ContactServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id="octopus", + ) + + +def test_contact_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.ads.admanager_v1.services.contact_service.transports.ContactServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ContactServiceTransport() + adc.assert_called_once() + + +def test_contact_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + ContactServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id=None, + ) + + +def test_contact_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.ContactServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_contact_service_host_no_port(transport_name): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_contact_service_host_with_port(transport_name): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_contact_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ContactServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ContactServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.get_contact._session + session2 = client2.transport.get_contact._session + assert session1 != session2 + session1 = client1.transport.list_contacts._session + session2 = client2.transport.list_contacts._session + assert session1 != session2 + session1 = client1.transport.create_contact._session + session2 = client2.transport.create_contact._session + assert session1 != session2 + session1 = client1.transport.batch_create_contacts._session + session2 = client2.transport.batch_create_contacts._session + assert session1 != session2 + session1 = client1.transport.update_contact._session + session2 = client2.transport.update_contact._session + assert session1 != session2 + session1 = client1.transport.batch_update_contacts._session + session2 = client2.transport.batch_update_contacts._session + assert session1 != session2 + + +def test_company_path(): + network_code = "squid" + company = "clam" + expected = "networks/{network_code}/companies/{company}".format( + network_code=network_code, + company=company, + ) + actual = ContactServiceClient.company_path(network_code, company) + assert expected == actual + + +def test_parse_company_path(): + expected = { + "network_code": "whelk", + "company": "octopus", + } + path = ContactServiceClient.company_path(**expected) + + # Check that the path construction is reversible. + actual = ContactServiceClient.parse_company_path(path) + assert expected == actual + + +def test_contact_path(): + network_code = "oyster" + contact = "nudibranch" + expected = "networks/{network_code}/contacts/{contact}".format( + network_code=network_code, + contact=contact, + ) + actual = ContactServiceClient.contact_path(network_code, contact) + assert expected == actual + + +def test_parse_contact_path(): + expected = { + "network_code": "cuttlefish", + "contact": "mussel", + } + path = ContactServiceClient.contact_path(**expected) + + # Check that the path construction is reversible. + actual = ContactServiceClient.parse_contact_path(path) + assert expected == actual + + +def test_network_path(): + network_code = "winkle" + expected = "networks/{network_code}".format( + network_code=network_code, + ) + actual = ContactServiceClient.network_path(network_code) + assert expected == actual + + +def test_parse_network_path(): + expected = { + "network_code": "nautilus", + } + path = ContactServiceClient.network_path(**expected) + + # Check that the path construction is reversible. + actual = ContactServiceClient.parse_network_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "scallop" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = ContactServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "abalone", + } + path = ContactServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ContactServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "squid" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = ContactServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "clam", + } + path = ContactServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ContactServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "whelk" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = ContactServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "octopus", + } + path = ContactServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ContactServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "oyster" + expected = "projects/{project}".format( + project=project, + ) + actual = ContactServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nudibranch", + } + path = ContactServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ContactServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "cuttlefish" + location = "mussel" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = ContactServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "winkle", + "location": "nautilus", + } + path = ContactServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ContactServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.ContactServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.ContactServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = ContactServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_rest(): + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + ] + for transport in transports: + client = ContactServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (ContactServiceClient, transports.ContactServiceRestTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_content_bundle_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_content_bundle_service.py new file mode 100644 index 000000000000..48d9607a6f3b --- /dev/null +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_content_bundle_service.py @@ -0,0 +1,2304 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account + +from google.ads.admanager_v1.services.content_bundle_service import ( + ContentBundleServiceClient, + pagers, + transports, +) +from google.ads.admanager_v1.types import ( + content_bundle_messages, + content_bundle_service, +) + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert ContentBundleServiceClient._get_default_mtls_endpoint(None) is None + assert ( + ContentBundleServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + ContentBundleServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + ContentBundleServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + ContentBundleServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + ContentBundleServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +def test__read_environment_variables(): + assert ContentBundleServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert ContentBundleServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert ContentBundleServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + ContentBundleServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert ContentBundleServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert ContentBundleServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert ContentBundleServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + ContentBundleServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert ContentBundleServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert ContentBundleServiceClient._get_client_cert_source(None, False) is None + assert ( + ContentBundleServiceClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + ContentBundleServiceClient._get_client_cert_source( + mock_provided_cert_source, True + ) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + ContentBundleServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + ContentBundleServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + ContentBundleServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ContentBundleServiceClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = ContentBundleServiceClient._DEFAULT_UNIVERSE + default_endpoint = ContentBundleServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = ContentBundleServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + ContentBundleServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + ContentBundleServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == ContentBundleServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + ContentBundleServiceClient._get_api_endpoint( + None, None, default_universe, "auto" + ) + == default_endpoint + ) + assert ( + ContentBundleServiceClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == ContentBundleServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + ContentBundleServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == ContentBundleServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + ContentBundleServiceClient._get_api_endpoint(None, None, mock_universe, "never") + == mock_endpoint + ) + assert ( + ContentBundleServiceClient._get_api_endpoint( + None, None, default_universe, "never" + ) + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + ContentBundleServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + ContentBundleServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + ContentBundleServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + ContentBundleServiceClient._get_universe_domain(None, None) + == ContentBundleServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + ContentBundleServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ContentBundleServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ContentBundleServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (ContentBundleServiceClient, "rest"), + ], +) +def test_content_bundle_service_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.ContentBundleServiceRestTransport, "rest"), + ], +) +def test_content_bundle_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (ContentBundleServiceClient, "rest"), + ], +) +def test_content_bundle_service_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +def test_content_bundle_service_client_get_transport_class(): + transport = ContentBundleServiceClient.get_transport_class() + available_transports = [ + transports.ContentBundleServiceRestTransport, + ] + assert transport in available_transports + + transport = ContentBundleServiceClient.get_transport_class("rest") + assert transport == transports.ContentBundleServiceRestTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + ContentBundleServiceClient, + transports.ContentBundleServiceRestTransport, + "rest", + ), + ], +) +@mock.patch.object( + ContentBundleServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ContentBundleServiceClient), +) +def test_content_bundle_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(ContentBundleServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(ContentBundleServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + ContentBundleServiceClient, + transports.ContentBundleServiceRestTransport, + "rest", + "true", + ), + ( + ContentBundleServiceClient, + transports.ContentBundleServiceRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + ContentBundleServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ContentBundleServiceClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_content_bundle_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [ContentBundleServiceClient]) +@mock.patch.object( + ContentBundleServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(ContentBundleServiceClient), +) +def test_content_bundle_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize("client_class", [ContentBundleServiceClient]) +@mock.patch.object( + ContentBundleServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ContentBundleServiceClient), +) +def test_content_bundle_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = ContentBundleServiceClient._DEFAULT_UNIVERSE + default_endpoint = ContentBundleServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = ContentBundleServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + ContentBundleServiceClient, + transports.ContentBundleServiceRestTransport, + "rest", + ), + ], +) +def test_content_bundle_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + ContentBundleServiceClient, + transports.ContentBundleServiceRestTransport, + "rest", + None, + ), + ], +) +def test_content_bundle_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_get_content_bundle_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_content_bundle in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_content_bundle + ] = mock_rpc + + request = {} + client.get_content_bundle(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_content_bundle(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_content_bundle_rest_required_fields( + request_type=content_bundle_service.GetContentBundleRequest, +): + transport_class = transports.ContentBundleServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_content_bundle._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_content_bundle._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = content_bundle_messages.ContentBundle() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = content_bundle_messages.ContentBundle.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_content_bundle(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_content_bundle_rest_unset_required_fields(): + transport = transports.ContentBundleServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_content_bundle._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_content_bundle_rest_flattened(): + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = content_bundle_messages.ContentBundle() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "networks/sample1/contentBundles/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = content_bundle_messages.ContentBundle.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_content_bundle(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=networks/*/contentBundles/*}" % client.transport._host, args[1] + ) + + +def test_get_content_bundle_rest_flattened_error(transport: str = "rest"): + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_content_bundle( + content_bundle_service.GetContentBundleRequest(), + name="name_value", + ) + + +def test_list_content_bundles_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_content_bundles in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_content_bundles + ] = mock_rpc + + request = {} + client.list_content_bundles(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_content_bundles(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_content_bundles_rest_required_fields( + request_type=content_bundle_service.ListContentBundlesRequest, +): + transport_class = transports.ContentBundleServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_content_bundles._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_content_bundles._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + "skip", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = content_bundle_service.ListContentBundlesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = content_bundle_service.ListContentBundlesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_content_bundles(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_content_bundles_rest_unset_required_fields(): + transport = transports.ContentBundleServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_content_bundles._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + "skip", + ) + ) + & set(("parent",)) + ) + + +def test_list_content_bundles_rest_flattened(): + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = content_bundle_service.ListContentBundlesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = content_bundle_service.ListContentBundlesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_content_bundles(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/contentBundles" % client.transport._host, args[1] + ) + + +def test_list_content_bundles_rest_flattened_error(transport: str = "rest"): + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_content_bundles( + content_bundle_service.ListContentBundlesRequest(), + parent="parent_value", + ) + + +def test_list_content_bundles_rest_pager(transport: str = "rest"): + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + content_bundle_service.ListContentBundlesResponse( + content_bundles=[ + content_bundle_messages.ContentBundle(), + content_bundle_messages.ContentBundle(), + content_bundle_messages.ContentBundle(), + ], + next_page_token="abc", + ), + content_bundle_service.ListContentBundlesResponse( + content_bundles=[], + next_page_token="def", + ), + content_bundle_service.ListContentBundlesResponse( + content_bundles=[ + content_bundle_messages.ContentBundle(), + ], + next_page_token="ghi", + ), + content_bundle_service.ListContentBundlesResponse( + content_bundles=[ + content_bundle_messages.ContentBundle(), + content_bundle_messages.ContentBundle(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + content_bundle_service.ListContentBundlesResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "networks/sample1"} + + pager = client.list_content_bundles(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, content_bundle_messages.ContentBundle) for i in results + ) + + pages = list(client.list_content_bundles(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ContentBundleServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ContentBundleServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ContentBundleServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ContentBundleServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ContentBundleServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ContentBundleServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ContentBundleServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ContentBundleServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ContentBundleServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ContentBundleServiceClient(transport=transport) + assert client.transport is transport + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ContentBundleServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_rest(): + transport = ContentBundleServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_content_bundle_rest_bad_request( + request_type=content_bundle_service.GetContentBundleRequest, +): + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/contentBundles/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_content_bundle(request) + + +@pytest.mark.parametrize( + "request_type", + [ + content_bundle_service.GetContentBundleRequest, + dict, + ], +) +def test_get_content_bundle_rest_call_success(request_type): + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/contentBundles/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = content_bundle_messages.ContentBundle( + name="name_value", + display_name="display_name_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = content_bundle_messages.ContentBundle.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_content_bundle(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, content_bundle_messages.ContentBundle) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_content_bundle_rest_interceptors(null_interceptor): + transport = transports.ContentBundleServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ContentBundleServiceRestInterceptor(), + ) + client = ContentBundleServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ContentBundleServiceRestInterceptor, "post_get_content_bundle" + ) as post, mock.patch.object( + transports.ContentBundleServiceRestInterceptor, + "post_get_content_bundle_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.ContentBundleServiceRestInterceptor, "pre_get_content_bundle" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = content_bundle_service.GetContentBundleRequest.pb( + content_bundle_service.GetContentBundleRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = content_bundle_messages.ContentBundle.to_json( + content_bundle_messages.ContentBundle() + ) + req.return_value.content = return_value + + request = content_bundle_service.GetContentBundleRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = content_bundle_messages.ContentBundle() + post_with_metadata.return_value = ( + content_bundle_messages.ContentBundle(), + metadata, + ) + + client.get_content_bundle( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_content_bundles_rest_bad_request( + request_type=content_bundle_service.ListContentBundlesRequest, +): + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_content_bundles(request) + + +@pytest.mark.parametrize( + "request_type", + [ + content_bundle_service.ListContentBundlesRequest, + dict, + ], +) +def test_list_content_bundles_rest_call_success(request_type): + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = content_bundle_service.ListContentBundlesResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = content_bundle_service.ListContentBundlesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_content_bundles(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListContentBundlesPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_content_bundles_rest_interceptors(null_interceptor): + transport = transports.ContentBundleServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ContentBundleServiceRestInterceptor(), + ) + client = ContentBundleServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ContentBundleServiceRestInterceptor, "post_list_content_bundles" + ) as post, mock.patch.object( + transports.ContentBundleServiceRestInterceptor, + "post_list_content_bundles_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.ContentBundleServiceRestInterceptor, "pre_list_content_bundles" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = content_bundle_service.ListContentBundlesRequest.pb( + content_bundle_service.ListContentBundlesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = content_bundle_service.ListContentBundlesResponse.to_json( + content_bundle_service.ListContentBundlesResponse() + ) + req.return_value.content = return_value + + request = content_bundle_service.ListContentBundlesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = content_bundle_service.ListContentBundlesResponse() + post_with_metadata.return_value = ( + content_bundle_service.ListContentBundlesResponse(), + metadata, + ) + + client.list_content_bundles( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "networks/sample1/operations/reports/runs/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "networks/sample1/operations/reports/runs/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_initialize_client_w_rest(): + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_content_bundle_empty_call_rest(): + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_content_bundle), "__call__" + ) as call: + client.get_content_bundle(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = content_bundle_service.GetContentBundleRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_content_bundles_empty_call_rest(): + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_content_bundles), "__call__" + ) as call: + client.list_content_bundles(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = content_bundle_service.ListContentBundlesRequest() + + assert args[0] == request_msg + + +def test_content_bundle_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ContentBundleServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_content_bundle_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.ads.admanager_v1.services.content_bundle_service.transports.ContentBundleServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.ContentBundleServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "get_content_bundle", + "list_content_bundles", + "get_operation", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_content_bundle_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.ads.admanager_v1.services.content_bundle_service.transports.ContentBundleServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ContentBundleServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id="octopus", + ) + + +def test_content_bundle_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.ads.admanager_v1.services.content_bundle_service.transports.ContentBundleServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ContentBundleServiceTransport() + adc.assert_called_once() + + +def test_content_bundle_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + ContentBundleServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id=None, + ) + + +def test_content_bundle_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.ContentBundleServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_content_bundle_service_host_no_port(transport_name): + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_content_bundle_service_host_with_port(transport_name): + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_content_bundle_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ContentBundleServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ContentBundleServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.get_content_bundle._session + session2 = client2.transport.get_content_bundle._session + assert session1 != session2 + session1 = client1.transport.list_content_bundles._session + session2 = client2.transport.list_content_bundles._session + assert session1 != session2 + + +def test_content_bundle_path(): + network_code = "squid" + content_bundle = "clam" + expected = "networks/{network_code}/contentBundles/{content_bundle}".format( + network_code=network_code, + content_bundle=content_bundle, + ) + actual = ContentBundleServiceClient.content_bundle_path( + network_code, content_bundle + ) + assert expected == actual + + +def test_parse_content_bundle_path(): + expected = { + "network_code": "whelk", + "content_bundle": "octopus", + } + path = ContentBundleServiceClient.content_bundle_path(**expected) + + # Check that the path construction is reversible. + actual = ContentBundleServiceClient.parse_content_bundle_path(path) + assert expected == actual + + +def test_network_path(): + network_code = "oyster" + expected = "networks/{network_code}".format( + network_code=network_code, + ) + actual = ContentBundleServiceClient.network_path(network_code) + assert expected == actual + + +def test_parse_network_path(): + expected = { + "network_code": "nudibranch", + } + path = ContentBundleServiceClient.network_path(**expected) + + # Check that the path construction is reversible. + actual = ContentBundleServiceClient.parse_network_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = ContentBundleServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = ContentBundleServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ContentBundleServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = ContentBundleServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = ContentBundleServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ContentBundleServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = ContentBundleServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = ContentBundleServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ContentBundleServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format( + project=project, + ) + actual = ContentBundleServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = ContentBundleServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ContentBundleServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = ContentBundleServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = ContentBundleServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ContentBundleServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.ContentBundleServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.ContentBundleServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = ContentBundleServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_rest(): + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + ] + for transport in transports: + client = ContentBundleServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (ContentBundleServiceClient, transports.ContentBundleServiceRestTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_content_label_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_content_label_service.py new file mode 100644 index 000000000000..8e79f6c0b76b --- /dev/null +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_content_label_service.py @@ -0,0 +1,2290 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account + +from google.ads.admanager_v1.services.content_label_service import ( + ContentLabelServiceClient, + pagers, + transports, +) +from google.ads.admanager_v1.types import content_label_messages, content_label_service + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert ContentLabelServiceClient._get_default_mtls_endpoint(None) is None + assert ( + ContentLabelServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + ContentLabelServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + ContentLabelServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + ContentLabelServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + ContentLabelServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +def test__read_environment_variables(): + assert ContentLabelServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert ContentLabelServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert ContentLabelServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + ContentLabelServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert ContentLabelServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert ContentLabelServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert ContentLabelServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + ContentLabelServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert ContentLabelServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert ContentLabelServiceClient._get_client_cert_source(None, False) is None + assert ( + ContentLabelServiceClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + ContentLabelServiceClient._get_client_cert_source( + mock_provided_cert_source, True + ) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + ContentLabelServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + ContentLabelServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + ContentLabelServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ContentLabelServiceClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = ContentLabelServiceClient._DEFAULT_UNIVERSE + default_endpoint = ContentLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = ContentLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + ContentLabelServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + ContentLabelServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == ContentLabelServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + ContentLabelServiceClient._get_api_endpoint( + None, None, default_universe, "auto" + ) + == default_endpoint + ) + assert ( + ContentLabelServiceClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == ContentLabelServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + ContentLabelServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == ContentLabelServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + ContentLabelServiceClient._get_api_endpoint(None, None, mock_universe, "never") + == mock_endpoint + ) + assert ( + ContentLabelServiceClient._get_api_endpoint( + None, None, default_universe, "never" + ) + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + ContentLabelServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + ContentLabelServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + ContentLabelServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + ContentLabelServiceClient._get_universe_domain(None, None) + == ContentLabelServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + ContentLabelServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ContentLabelServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ContentLabelServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (ContentLabelServiceClient, "rest"), + ], +) +def test_content_label_service_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.ContentLabelServiceRestTransport, "rest"), + ], +) +def test_content_label_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (ContentLabelServiceClient, "rest"), + ], +) +def test_content_label_service_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +def test_content_label_service_client_get_transport_class(): + transport = ContentLabelServiceClient.get_transport_class() + available_transports = [ + transports.ContentLabelServiceRestTransport, + ] + assert transport in available_transports + + transport = ContentLabelServiceClient.get_transport_class("rest") + assert transport == transports.ContentLabelServiceRestTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + ContentLabelServiceClient, + transports.ContentLabelServiceRestTransport, + "rest", + ), + ], +) +@mock.patch.object( + ContentLabelServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ContentLabelServiceClient), +) +def test_content_label_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(ContentLabelServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(ContentLabelServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + ContentLabelServiceClient, + transports.ContentLabelServiceRestTransport, + "rest", + "true", + ), + ( + ContentLabelServiceClient, + transports.ContentLabelServiceRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + ContentLabelServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ContentLabelServiceClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_content_label_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [ContentLabelServiceClient]) +@mock.patch.object( + ContentLabelServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(ContentLabelServiceClient), +) +def test_content_label_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize("client_class", [ContentLabelServiceClient]) +@mock.patch.object( + ContentLabelServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ContentLabelServiceClient), +) +def test_content_label_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = ContentLabelServiceClient._DEFAULT_UNIVERSE + default_endpoint = ContentLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = ContentLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + ContentLabelServiceClient, + transports.ContentLabelServiceRestTransport, + "rest", + ), + ], +) +def test_content_label_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + ContentLabelServiceClient, + transports.ContentLabelServiceRestTransport, + "rest", + None, + ), + ], +) +def test_content_label_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_get_content_label_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_content_label in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_content_label + ] = mock_rpc + + request = {} + client.get_content_label(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_content_label(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_content_label_rest_required_fields( + request_type=content_label_service.GetContentLabelRequest, +): + transport_class = transports.ContentLabelServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_content_label._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_content_label._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = content_label_messages.ContentLabel() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = content_label_messages.ContentLabel.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_content_label(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_content_label_rest_unset_required_fields(): + transport = transports.ContentLabelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_content_label._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_content_label_rest_flattened(): + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = content_label_messages.ContentLabel() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "networks/sample1/contentLabels/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = content_label_messages.ContentLabel.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_content_label(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=networks/*/contentLabels/*}" % client.transport._host, args[1] + ) + + +def test_get_content_label_rest_flattened_error(transport: str = "rest"): + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_content_label( + content_label_service.GetContentLabelRequest(), + name="name_value", + ) + + +def test_list_content_labels_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_content_labels in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_content_labels + ] = mock_rpc + + request = {} + client.list_content_labels(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_content_labels(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_content_labels_rest_required_fields( + request_type=content_label_service.ListContentLabelsRequest, +): + transport_class = transports.ContentLabelServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_content_labels._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_content_labels._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + "skip", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = content_label_service.ListContentLabelsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = content_label_service.ListContentLabelsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_content_labels(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_content_labels_rest_unset_required_fields(): + transport = transports.ContentLabelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_content_labels._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + "skip", + ) + ) + & set(("parent",)) + ) + + +def test_list_content_labels_rest_flattened(): + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = content_label_service.ListContentLabelsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = content_label_service.ListContentLabelsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_content_labels(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/contentLabels" % client.transport._host, args[1] + ) + + +def test_list_content_labels_rest_flattened_error(transport: str = "rest"): + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_content_labels( + content_label_service.ListContentLabelsRequest(), + parent="parent_value", + ) + + +def test_list_content_labels_rest_pager(transport: str = "rest"): + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + content_label_service.ListContentLabelsResponse( + content_labels=[ + content_label_messages.ContentLabel(), + content_label_messages.ContentLabel(), + content_label_messages.ContentLabel(), + ], + next_page_token="abc", + ), + content_label_service.ListContentLabelsResponse( + content_labels=[], + next_page_token="def", + ), + content_label_service.ListContentLabelsResponse( + content_labels=[ + content_label_messages.ContentLabel(), + ], + next_page_token="ghi", + ), + content_label_service.ListContentLabelsResponse( + content_labels=[ + content_label_messages.ContentLabel(), + content_label_messages.ContentLabel(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + content_label_service.ListContentLabelsResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "networks/sample1"} + + pager = client.list_content_labels(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, content_label_messages.ContentLabel) for i in results) + + pages = list(client.list_content_labels(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ContentLabelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ContentLabelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ContentLabelServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ContentLabelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ContentLabelServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ContentLabelServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ContentLabelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ContentLabelServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ContentLabelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ContentLabelServiceClient(transport=transport) + assert client.transport is transport + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ContentLabelServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_rest(): + transport = ContentLabelServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_content_label_rest_bad_request( + request_type=content_label_service.GetContentLabelRequest, +): + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/contentLabels/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_content_label(request) + + +@pytest.mark.parametrize( + "request_type", + [ + content_label_service.GetContentLabelRequest, + dict, + ], +) +def test_get_content_label_rest_call_success(request_type): + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/contentLabels/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = content_label_messages.ContentLabel( + name="name_value", + display_name="display_name_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = content_label_messages.ContentLabel.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_content_label(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, content_label_messages.ContentLabel) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_content_label_rest_interceptors(null_interceptor): + transport = transports.ContentLabelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ContentLabelServiceRestInterceptor(), + ) + client = ContentLabelServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ContentLabelServiceRestInterceptor, "post_get_content_label" + ) as post, mock.patch.object( + transports.ContentLabelServiceRestInterceptor, + "post_get_content_label_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.ContentLabelServiceRestInterceptor, "pre_get_content_label" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = content_label_service.GetContentLabelRequest.pb( + content_label_service.GetContentLabelRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = content_label_messages.ContentLabel.to_json( + content_label_messages.ContentLabel() + ) + req.return_value.content = return_value + + request = content_label_service.GetContentLabelRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = content_label_messages.ContentLabel() + post_with_metadata.return_value = ( + content_label_messages.ContentLabel(), + metadata, + ) + + client.get_content_label( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_content_labels_rest_bad_request( + request_type=content_label_service.ListContentLabelsRequest, +): + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_content_labels(request) + + +@pytest.mark.parametrize( + "request_type", + [ + content_label_service.ListContentLabelsRequest, + dict, + ], +) +def test_list_content_labels_rest_call_success(request_type): + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = content_label_service.ListContentLabelsResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = content_label_service.ListContentLabelsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_content_labels(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListContentLabelsPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_content_labels_rest_interceptors(null_interceptor): + transport = transports.ContentLabelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ContentLabelServiceRestInterceptor(), + ) + client = ContentLabelServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ContentLabelServiceRestInterceptor, "post_list_content_labels" + ) as post, mock.patch.object( + transports.ContentLabelServiceRestInterceptor, + "post_list_content_labels_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.ContentLabelServiceRestInterceptor, "pre_list_content_labels" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = content_label_service.ListContentLabelsRequest.pb( + content_label_service.ListContentLabelsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = content_label_service.ListContentLabelsResponse.to_json( + content_label_service.ListContentLabelsResponse() + ) + req.return_value.content = return_value + + request = content_label_service.ListContentLabelsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = content_label_service.ListContentLabelsResponse() + post_with_metadata.return_value = ( + content_label_service.ListContentLabelsResponse(), + metadata, + ) + + client.list_content_labels( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "networks/sample1/operations/reports/runs/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "networks/sample1/operations/reports/runs/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_initialize_client_w_rest(): + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_content_label_empty_call_rest(): + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_content_label), "__call__" + ) as call: + client.get_content_label(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = content_label_service.GetContentLabelRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_content_labels_empty_call_rest(): + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_content_labels), "__call__" + ) as call: + client.list_content_labels(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = content_label_service.ListContentLabelsRequest() + + assert args[0] == request_msg + + +def test_content_label_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ContentLabelServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_content_label_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.ads.admanager_v1.services.content_label_service.transports.ContentLabelServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.ContentLabelServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "get_content_label", + "list_content_labels", + "get_operation", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_content_label_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.ads.admanager_v1.services.content_label_service.transports.ContentLabelServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ContentLabelServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id="octopus", + ) + + +def test_content_label_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.ads.admanager_v1.services.content_label_service.transports.ContentLabelServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ContentLabelServiceTransport() + adc.assert_called_once() + + +def test_content_label_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + ContentLabelServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id=None, + ) + + +def test_content_label_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.ContentLabelServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_content_label_service_host_no_port(transport_name): + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_content_label_service_host_with_port(transport_name): + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_content_label_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ContentLabelServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ContentLabelServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.get_content_label._session + session2 = client2.transport.get_content_label._session + assert session1 != session2 + session1 = client1.transport.list_content_labels._session + session2 = client2.transport.list_content_labels._session + assert session1 != session2 + + +def test_content_label_path(): + network_code = "squid" + content_label = "clam" + expected = "networks/{network_code}/contentLabels/{content_label}".format( + network_code=network_code, + content_label=content_label, + ) + actual = ContentLabelServiceClient.content_label_path(network_code, content_label) + assert expected == actual + + +def test_parse_content_label_path(): + expected = { + "network_code": "whelk", + "content_label": "octopus", + } + path = ContentLabelServiceClient.content_label_path(**expected) + + # Check that the path construction is reversible. + actual = ContentLabelServiceClient.parse_content_label_path(path) + assert expected == actual + + +def test_network_path(): + network_code = "oyster" + expected = "networks/{network_code}".format( + network_code=network_code, + ) + actual = ContentLabelServiceClient.network_path(network_code) + assert expected == actual + + +def test_parse_network_path(): + expected = { + "network_code": "nudibranch", + } + path = ContentLabelServiceClient.network_path(**expected) + + # Check that the path construction is reversible. + actual = ContentLabelServiceClient.parse_network_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = ContentLabelServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = ContentLabelServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ContentLabelServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = ContentLabelServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = ContentLabelServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ContentLabelServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = ContentLabelServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = ContentLabelServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ContentLabelServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format( + project=project, + ) + actual = ContentLabelServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = ContentLabelServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ContentLabelServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = ContentLabelServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = ContentLabelServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ContentLabelServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.ContentLabelServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.ContentLabelServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = ContentLabelServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_rest(): + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + ] + for transport in transports: + client = ContentLabelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (ContentLabelServiceClient, transports.ContentLabelServiceRestTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_content_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_content_service.py new file mode 100644 index 000000000000..da7d64cecc31 --- /dev/null +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_content_service.py @@ -0,0 +1,2225 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account + +from google.ads.admanager_v1.services.content_service import ( + ContentServiceClient, + pagers, + transports, +) +from google.ads.admanager_v1.types import content_messages, content_service + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert ContentServiceClient._get_default_mtls_endpoint(None) is None + assert ( + ContentServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + ContentServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + ContentServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + ContentServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + ContentServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + ) + + +def test__read_environment_variables(): + assert ContentServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert ContentServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert ContentServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + ContentServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert ContentServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert ContentServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert ContentServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + ContentServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert ContentServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert ContentServiceClient._get_client_cert_source(None, False) is None + assert ( + ContentServiceClient._get_client_cert_source(mock_provided_cert_source, False) + is None + ) + assert ( + ContentServiceClient._get_client_cert_source(mock_provided_cert_source, True) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + ContentServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + ContentServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + ContentServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ContentServiceClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = ContentServiceClient._DEFAULT_UNIVERSE + default_endpoint = ContentServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = ContentServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + ContentServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + ContentServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == ContentServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + ContentServiceClient._get_api_endpoint(None, None, default_universe, "auto") + == default_endpoint + ) + assert ( + ContentServiceClient._get_api_endpoint(None, None, default_universe, "always") + == ContentServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + ContentServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == ContentServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + ContentServiceClient._get_api_endpoint(None, None, mock_universe, "never") + == mock_endpoint + ) + assert ( + ContentServiceClient._get_api_endpoint(None, None, default_universe, "never") + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + ContentServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + ContentServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + ContentServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + ContentServiceClient._get_universe_domain(None, None) + == ContentServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + ContentServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ContentServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ContentServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (ContentServiceClient, "rest"), + ], +) +def test_content_service_client_from_service_account_info(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.ContentServiceRestTransport, "rest"), + ], +) +def test_content_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (ContentServiceClient, "rest"), + ], +) +def test_content_service_client_from_service_account_file(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +def test_content_service_client_get_transport_class(): + transport = ContentServiceClient.get_transport_class() + available_transports = [ + transports.ContentServiceRestTransport, + ] + assert transport in available_transports + + transport = ContentServiceClient.get_transport_class("rest") + assert transport == transports.ContentServiceRestTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (ContentServiceClient, transports.ContentServiceRestTransport, "rest"), + ], +) +@mock.patch.object( + ContentServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ContentServiceClient), +) +def test_content_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(ContentServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(ContentServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + (ContentServiceClient, transports.ContentServiceRestTransport, "rest", "true"), + (ContentServiceClient, transports.ContentServiceRestTransport, "rest", "false"), + ], +) +@mock.patch.object( + ContentServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ContentServiceClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_content_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [ContentServiceClient]) +@mock.patch.object( + ContentServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(ContentServiceClient), +) +def test_content_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize("client_class", [ContentServiceClient]) +@mock.patch.object( + ContentServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ContentServiceClient), +) +def test_content_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = ContentServiceClient._DEFAULT_UNIVERSE + default_endpoint = ContentServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = ContentServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (ContentServiceClient, transports.ContentServiceRestTransport, "rest"), + ], +) +def test_content_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + (ContentServiceClient, transports.ContentServiceRestTransport, "rest", None), + ], +) +def test_content_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_get_content_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_content in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_content] = mock_rpc + + request = {} + client.get_content(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_content(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_content_rest_required_fields( + request_type=content_service.GetContentRequest, +): + transport_class = transports.ContentServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_content._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_content._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = content_messages.Content() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = content_messages.Content.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_content(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_content_rest_unset_required_fields(): + transport = transports.ContentServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_content._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_content_rest_flattened(): + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = content_messages.Content() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "networks/sample1/content/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = content_messages.Content.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_content(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=networks/*/content/*}" % client.transport._host, args[1] + ) + + +def test_get_content_rest_flattened_error(transport: str = "rest"): + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_content( + content_service.GetContentRequest(), + name="name_value", + ) + + +def test_list_content_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_content in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_content] = mock_rpc + + request = {} + client.list_content(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_content(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_content_rest_required_fields( + request_type=content_service.ListContentRequest, +): + transport_class = transports.ContentServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_content._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_content._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + "skip", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = content_service.ListContentResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = content_service.ListContentResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_content(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_content_rest_unset_required_fields(): + transport = transports.ContentServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_content._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + "skip", + ) + ) + & set(("parent",)) + ) + + +def test_list_content_rest_flattened(): + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = content_service.ListContentResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = content_service.ListContentResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_content(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/content" % client.transport._host, args[1] + ) + + +def test_list_content_rest_flattened_error(transport: str = "rest"): + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_content( + content_service.ListContentRequest(), + parent="parent_value", + ) + + +def test_list_content_rest_pager(transport: str = "rest"): + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + content_service.ListContentResponse( + content=[ + content_messages.Content(), + content_messages.Content(), + content_messages.Content(), + ], + next_page_token="abc", + ), + content_service.ListContentResponse( + content=[], + next_page_token="def", + ), + content_service.ListContentResponse( + content=[ + content_messages.Content(), + ], + next_page_token="ghi", + ), + content_service.ListContentResponse( + content=[ + content_messages.Content(), + content_messages.Content(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + content_service.ListContentResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "networks/sample1"} + + pager = client.list_content(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, content_messages.Content) for i in results) + + pages = list(client.list_content(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ContentServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ContentServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ContentServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ContentServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ContentServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ContentServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ContentServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ContentServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ContentServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ContentServiceClient(transport=transport) + assert client.transport is transport + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ContentServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_rest(): + transport = ContentServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_content_rest_bad_request(request_type=content_service.GetContentRequest): + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/content/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_content(request) + + +@pytest.mark.parametrize( + "request_type", + [ + content_service.GetContentRequest, + dict, + ], +) +def test_get_content_rest_call_success(request_type): + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/content/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = content_messages.Content( + name="name_value", + display_name="display_name_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = content_messages.Content.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_content(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, content_messages.Content) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_content_rest_interceptors(null_interceptor): + transport = transports.ContentServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ContentServiceRestInterceptor(), + ) + client = ContentServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ContentServiceRestInterceptor, "post_get_content" + ) as post, mock.patch.object( + transports.ContentServiceRestInterceptor, "post_get_content_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.ContentServiceRestInterceptor, "pre_get_content" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = content_service.GetContentRequest.pb( + content_service.GetContentRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = content_messages.Content.to_json(content_messages.Content()) + req.return_value.content = return_value + + request = content_service.GetContentRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = content_messages.Content() + post_with_metadata.return_value = content_messages.Content(), metadata + + client.get_content( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_content_rest_bad_request(request_type=content_service.ListContentRequest): + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_content(request) + + +@pytest.mark.parametrize( + "request_type", + [ + content_service.ListContentRequest, + dict, + ], +) +def test_list_content_rest_call_success(request_type): + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = content_service.ListContentResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = content_service.ListContentResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_content(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListContentPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_content_rest_interceptors(null_interceptor): + transport = transports.ContentServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.ContentServiceRestInterceptor(), + ) + client = ContentServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ContentServiceRestInterceptor, "post_list_content" + ) as post, mock.patch.object( + transports.ContentServiceRestInterceptor, "post_list_content_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.ContentServiceRestInterceptor, "pre_list_content" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = content_service.ListContentRequest.pb( + content_service.ListContentRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = content_service.ListContentResponse.to_json( + content_service.ListContentResponse() + ) + req.return_value.content = return_value + + request = content_service.ListContentRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = content_service.ListContentResponse() + post_with_metadata.return_value = ( + content_service.ListContentResponse(), + metadata, + ) + + client.list_content( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "networks/sample1/operations/reports/runs/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "networks/sample1/operations/reports/runs/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_initialize_client_w_rest(): + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_content_empty_call_rest(): + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_content), "__call__") as call: + client.get_content(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = content_service.GetContentRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_content_empty_call_rest(): + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_content), "__call__") as call: + client.list_content(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = content_service.ListContentRequest() + + assert args[0] == request_msg + + +def test_content_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ContentServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_content_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.ads.admanager_v1.services.content_service.transports.ContentServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.ContentServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "get_content", + "list_content", + "get_operation", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_content_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.ads.admanager_v1.services.content_service.transports.ContentServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ContentServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id="octopus", + ) + + +def test_content_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.ads.admanager_v1.services.content_service.transports.ContentServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ContentServiceTransport() + adc.assert_called_once() + + +def test_content_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + ContentServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id=None, + ) + + +def test_content_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.ContentServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_content_service_host_no_port(transport_name): + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_content_service_host_with_port(transport_name): + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_content_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ContentServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ContentServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.get_content._session + session2 = client2.transport.get_content._session + assert session1 != session2 + session1 = client1.transport.list_content._session + session2 = client2.transport.list_content._session + assert session1 != session2 + + +def test_content_path(): + network_code = "squid" + content = "clam" + expected = "networks/{network_code}/content/{content}".format( + network_code=network_code, + content=content, + ) + actual = ContentServiceClient.content_path(network_code, content) + assert expected == actual + + +def test_parse_content_path(): + expected = { + "network_code": "whelk", + "content": "octopus", + } + path = ContentServiceClient.content_path(**expected) + + # Check that the path construction is reversible. + actual = ContentServiceClient.parse_content_path(path) + assert expected == actual + + +def test_network_path(): + network_code = "oyster" + expected = "networks/{network_code}".format( + network_code=network_code, + ) + actual = ContentServiceClient.network_path(network_code) + assert expected == actual + + +def test_parse_network_path(): + expected = { + "network_code": "nudibranch", + } + path = ContentServiceClient.network_path(**expected) + + # Check that the path construction is reversible. + actual = ContentServiceClient.parse_network_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = ContentServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = ContentServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ContentServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = ContentServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = ContentServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ContentServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = ContentServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = ContentServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ContentServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format( + project=project, + ) + actual = ContentServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = ContentServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ContentServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = ContentServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = ContentServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ContentServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.ContentServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.ContentServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = ContentServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_rest(): + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + ] + for transport in transports: + client = ContentServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (ContentServiceClient, transports.ContentServiceRestTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_creative_template_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_creative_template_service.py new file mode 100644 index 000000000000..3a14777faa90 --- /dev/null +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_creative_template_service.py @@ -0,0 +1,2339 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account + +from google.ads.admanager_v1.services.creative_template_service import ( + CreativeTemplateServiceClient, + pagers, + transports, +) +from google.ads.admanager_v1.types import ( + creative_template_enums, + creative_template_messages, + creative_template_service, +) + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert CreativeTemplateServiceClient._get_default_mtls_endpoint(None) is None + assert ( + CreativeTemplateServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + CreativeTemplateServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + CreativeTemplateServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + CreativeTemplateServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + CreativeTemplateServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +def test__read_environment_variables(): + assert CreativeTemplateServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert CreativeTemplateServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert CreativeTemplateServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + CreativeTemplateServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert CreativeTemplateServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert CreativeTemplateServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert CreativeTemplateServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + CreativeTemplateServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert CreativeTemplateServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert CreativeTemplateServiceClient._get_client_cert_source(None, False) is None + assert ( + CreativeTemplateServiceClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + CreativeTemplateServiceClient._get_client_cert_source( + mock_provided_cert_source, True + ) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + CreativeTemplateServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + CreativeTemplateServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + CreativeTemplateServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(CreativeTemplateServiceClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = CreativeTemplateServiceClient._DEFAULT_UNIVERSE + default_endpoint = CreativeTemplateServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = CreativeTemplateServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + CreativeTemplateServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + CreativeTemplateServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == CreativeTemplateServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + CreativeTemplateServiceClient._get_api_endpoint( + None, None, default_universe, "auto" + ) + == default_endpoint + ) + assert ( + CreativeTemplateServiceClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == CreativeTemplateServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + CreativeTemplateServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == CreativeTemplateServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + CreativeTemplateServiceClient._get_api_endpoint( + None, None, mock_universe, "never" + ) + == mock_endpoint + ) + assert ( + CreativeTemplateServiceClient._get_api_endpoint( + None, None, default_universe, "never" + ) + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + CreativeTemplateServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + CreativeTemplateServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + CreativeTemplateServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + CreativeTemplateServiceClient._get_universe_domain(None, None) + == CreativeTemplateServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + CreativeTemplateServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = CreativeTemplateServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = CreativeTemplateServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (CreativeTemplateServiceClient, "rest"), + ], +) +def test_creative_template_service_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.CreativeTemplateServiceRestTransport, "rest"), + ], +) +def test_creative_template_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (CreativeTemplateServiceClient, "rest"), + ], +) +def test_creative_template_service_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +def test_creative_template_service_client_get_transport_class(): + transport = CreativeTemplateServiceClient.get_transport_class() + available_transports = [ + transports.CreativeTemplateServiceRestTransport, + ] + assert transport in available_transports + + transport = CreativeTemplateServiceClient.get_transport_class("rest") + assert transport == transports.CreativeTemplateServiceRestTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + CreativeTemplateServiceClient, + transports.CreativeTemplateServiceRestTransport, + "rest", + ), + ], +) +@mock.patch.object( + CreativeTemplateServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(CreativeTemplateServiceClient), +) +def test_creative_template_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(CreativeTemplateServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(CreativeTemplateServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + CreativeTemplateServiceClient, + transports.CreativeTemplateServiceRestTransport, + "rest", + "true", + ), + ( + CreativeTemplateServiceClient, + transports.CreativeTemplateServiceRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + CreativeTemplateServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(CreativeTemplateServiceClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_creative_template_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [CreativeTemplateServiceClient]) +@mock.patch.object( + CreativeTemplateServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(CreativeTemplateServiceClient), +) +def test_creative_template_service_client_get_mtls_endpoint_and_cert_source( + client_class, +): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize("client_class", [CreativeTemplateServiceClient]) +@mock.patch.object( + CreativeTemplateServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(CreativeTemplateServiceClient), +) +def test_creative_template_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = CreativeTemplateServiceClient._DEFAULT_UNIVERSE + default_endpoint = CreativeTemplateServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = CreativeTemplateServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + CreativeTemplateServiceClient, + transports.CreativeTemplateServiceRestTransport, + "rest", + ), + ], +) +def test_creative_template_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + CreativeTemplateServiceClient, + transports.CreativeTemplateServiceRestTransport, + "rest", + None, + ), + ], +) +def test_creative_template_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_get_creative_template_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_creative_template + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_creative_template + ] = mock_rpc + + request = {} + client.get_creative_template(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_creative_template(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_creative_template_rest_required_fields( + request_type=creative_template_service.GetCreativeTemplateRequest, +): + transport_class = transports.CreativeTemplateServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_creative_template._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_creative_template._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = creative_template_messages.CreativeTemplate() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = creative_template_messages.CreativeTemplate.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_creative_template(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_creative_template_rest_unset_required_fields(): + transport = transports.CreativeTemplateServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_creative_template._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_creative_template_rest_flattened(): + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = creative_template_messages.CreativeTemplate() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "networks/sample1/creativeTemplates/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = creative_template_messages.CreativeTemplate.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_creative_template(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=networks/*/creativeTemplates/*}" % client.transport._host, + args[1], + ) + + +def test_get_creative_template_rest_flattened_error(transport: str = "rest"): + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_creative_template( + creative_template_service.GetCreativeTemplateRequest(), + name="name_value", + ) + + +def test_list_creative_templates_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_creative_templates + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_creative_templates + ] = mock_rpc + + request = {} + client.list_creative_templates(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_creative_templates(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_creative_templates_rest_required_fields( + request_type=creative_template_service.ListCreativeTemplatesRequest, +): + transport_class = transports.CreativeTemplateServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_creative_templates._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_creative_templates._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + "skip", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = creative_template_service.ListCreativeTemplatesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = creative_template_service.ListCreativeTemplatesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_creative_templates(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_creative_templates_rest_unset_required_fields(): + transport = transports.CreativeTemplateServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_creative_templates._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + "skip", + ) + ) + & set(("parent",)) + ) + + +def test_list_creative_templates_rest_flattened(): + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = creative_template_service.ListCreativeTemplatesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = creative_template_service.ListCreativeTemplatesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_creative_templates(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/creativeTemplates" % client.transport._host, + args[1], + ) + + +def test_list_creative_templates_rest_flattened_error(transport: str = "rest"): + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_creative_templates( + creative_template_service.ListCreativeTemplatesRequest(), + parent="parent_value", + ) + + +def test_list_creative_templates_rest_pager(transport: str = "rest"): + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + creative_template_service.ListCreativeTemplatesResponse( + creative_templates=[ + creative_template_messages.CreativeTemplate(), + creative_template_messages.CreativeTemplate(), + creative_template_messages.CreativeTemplate(), + ], + next_page_token="abc", + ), + creative_template_service.ListCreativeTemplatesResponse( + creative_templates=[], + next_page_token="def", + ), + creative_template_service.ListCreativeTemplatesResponse( + creative_templates=[ + creative_template_messages.CreativeTemplate(), + ], + next_page_token="ghi", + ), + creative_template_service.ListCreativeTemplatesResponse( + creative_templates=[ + creative_template_messages.CreativeTemplate(), + creative_template_messages.CreativeTemplate(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + creative_template_service.ListCreativeTemplatesResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "networks/sample1"} + + pager = client.list_creative_templates(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, creative_template_messages.CreativeTemplate) for i in results + ) + + pages = list(client.list_creative_templates(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.CreativeTemplateServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.CreativeTemplateServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CreativeTemplateServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.CreativeTemplateServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CreativeTemplateServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CreativeTemplateServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.CreativeTemplateServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CreativeTemplateServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.CreativeTemplateServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = CreativeTemplateServiceClient(transport=transport) + assert client.transport is transport + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CreativeTemplateServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_rest(): + transport = CreativeTemplateServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_creative_template_rest_bad_request( + request_type=creative_template_service.GetCreativeTemplateRequest, +): + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/creativeTemplates/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_creative_template(request) + + +@pytest.mark.parametrize( + "request_type", + [ + creative_template_service.GetCreativeTemplateRequest, + dict, + ], +) +def test_get_creative_template_rest_call_success(request_type): + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/creativeTemplates/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = creative_template_messages.CreativeTemplate( + name="name_value", + display_name="display_name_value", + description="description_value", + snippet="snippet_value", + status=creative_template_enums.CreativeTemplateStatusEnum.CreativeTemplateStatus.ACTIVE, + type_=creative_template_enums.CreativeTemplateTypeEnum.CreativeTemplateType.STANDARD, + interstitial=True, + native_eligible=True, + native_video_eligible=True, + safe_frame_compatible=True, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = creative_template_messages.CreativeTemplate.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_creative_template(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, creative_template_messages.CreativeTemplate) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.snippet == "snippet_value" + assert ( + response.status + == creative_template_enums.CreativeTemplateStatusEnum.CreativeTemplateStatus.ACTIVE + ) + assert ( + response.type_ + == creative_template_enums.CreativeTemplateTypeEnum.CreativeTemplateType.STANDARD + ) + assert response.interstitial is True + assert response.native_eligible is True + assert response.native_video_eligible is True + assert response.safe_frame_compatible is True + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_creative_template_rest_interceptors(null_interceptor): + transport = transports.CreativeTemplateServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.CreativeTemplateServiceRestInterceptor(), + ) + client = CreativeTemplateServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.CreativeTemplateServiceRestInterceptor, "post_get_creative_template" + ) as post, mock.patch.object( + transports.CreativeTemplateServiceRestInterceptor, + "post_get_creative_template_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.CreativeTemplateServiceRestInterceptor, "pre_get_creative_template" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = creative_template_service.GetCreativeTemplateRequest.pb( + creative_template_service.GetCreativeTemplateRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = creative_template_messages.CreativeTemplate.to_json( + creative_template_messages.CreativeTemplate() + ) + req.return_value.content = return_value + + request = creative_template_service.GetCreativeTemplateRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = creative_template_messages.CreativeTemplate() + post_with_metadata.return_value = ( + creative_template_messages.CreativeTemplate(), + metadata, + ) + + client.get_creative_template( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_creative_templates_rest_bad_request( + request_type=creative_template_service.ListCreativeTemplatesRequest, +): + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_creative_templates(request) + + +@pytest.mark.parametrize( + "request_type", + [ + creative_template_service.ListCreativeTemplatesRequest, + dict, + ], +) +def test_list_creative_templates_rest_call_success(request_type): + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = creative_template_service.ListCreativeTemplatesResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = creative_template_service.ListCreativeTemplatesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_creative_templates(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListCreativeTemplatesPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_creative_templates_rest_interceptors(null_interceptor): + transport = transports.CreativeTemplateServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.CreativeTemplateServiceRestInterceptor(), + ) + client = CreativeTemplateServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.CreativeTemplateServiceRestInterceptor, + "post_list_creative_templates", + ) as post, mock.patch.object( + transports.CreativeTemplateServiceRestInterceptor, + "post_list_creative_templates_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.CreativeTemplateServiceRestInterceptor, "pre_list_creative_templates" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = creative_template_service.ListCreativeTemplatesRequest.pb( + creative_template_service.ListCreativeTemplatesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = creative_template_service.ListCreativeTemplatesResponse.to_json( + creative_template_service.ListCreativeTemplatesResponse() + ) + req.return_value.content = return_value + + request = creative_template_service.ListCreativeTemplatesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = creative_template_service.ListCreativeTemplatesResponse() + post_with_metadata.return_value = ( + creative_template_service.ListCreativeTemplatesResponse(), + metadata, + ) + + client.list_creative_templates( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "networks/sample1/operations/reports/runs/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "networks/sample1/operations/reports/runs/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_initialize_client_w_rest(): + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_creative_template_empty_call_rest(): + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_creative_template), "__call__" + ) as call: + client.get_creative_template(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = creative_template_service.GetCreativeTemplateRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_creative_templates_empty_call_rest(): + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_creative_templates), "__call__" + ) as call: + client.list_creative_templates(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = creative_template_service.ListCreativeTemplatesRequest() + + assert args[0] == request_msg + + +def test_creative_template_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.CreativeTemplateServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_creative_template_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.ads.admanager_v1.services.creative_template_service.transports.CreativeTemplateServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.CreativeTemplateServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "get_creative_template", + "list_creative_templates", + "get_operation", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_creative_template_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.ads.admanager_v1.services.creative_template_service.transports.CreativeTemplateServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CreativeTemplateServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id="octopus", + ) + + +def test_creative_template_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.ads.admanager_v1.services.creative_template_service.transports.CreativeTemplateServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CreativeTemplateServiceTransport() + adc.assert_called_once() + + +def test_creative_template_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + CreativeTemplateServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id=None, + ) + + +def test_creative_template_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.CreativeTemplateServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_creative_template_service_host_no_port(transport_name): + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_creative_template_service_host_with_port(transport_name): + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_creative_template_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = CreativeTemplateServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = CreativeTemplateServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.get_creative_template._session + session2 = client2.transport.get_creative_template._session + assert session1 != session2 + session1 = client1.transport.list_creative_templates._session + session2 = client2.transport.list_creative_templates._session + assert session1 != session2 + + +def test_creative_template_path(): + network_code = "squid" + creative_template = "clam" + expected = "networks/{network_code}/creativeTemplates/{creative_template}".format( + network_code=network_code, + creative_template=creative_template, + ) + actual = CreativeTemplateServiceClient.creative_template_path( + network_code, creative_template + ) + assert expected == actual + + +def test_parse_creative_template_path(): + expected = { + "network_code": "whelk", + "creative_template": "octopus", + } + path = CreativeTemplateServiceClient.creative_template_path(**expected) + + # Check that the path construction is reversible. + actual = CreativeTemplateServiceClient.parse_creative_template_path(path) + assert expected == actual + + +def test_network_path(): + network_code = "oyster" + expected = "networks/{network_code}".format( + network_code=network_code, + ) + actual = CreativeTemplateServiceClient.network_path(network_code) + assert expected == actual + + +def test_parse_network_path(): + expected = { + "network_code": "nudibranch", + } + path = CreativeTemplateServiceClient.network_path(**expected) + + # Check that the path construction is reversible. + actual = CreativeTemplateServiceClient.parse_network_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = CreativeTemplateServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = CreativeTemplateServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = CreativeTemplateServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = CreativeTemplateServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = CreativeTemplateServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = CreativeTemplateServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = CreativeTemplateServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = CreativeTemplateServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = CreativeTemplateServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format( + project=project, + ) + actual = CreativeTemplateServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = CreativeTemplateServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = CreativeTemplateServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = CreativeTemplateServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = CreativeTemplateServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = CreativeTemplateServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.CreativeTemplateServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.CreativeTemplateServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = CreativeTemplateServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_rest(): + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + ] + for transport in transports: + client = CreativeTemplateServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + ( + CreativeTemplateServiceClient, + transports.CreativeTemplateServiceRestTransport, + ), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_custom_field_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_custom_field_service.py index 70633fe8dec1..ffb5ec0762ec 100644 --- a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_custom_field_service.py +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_custom_field_service.py @@ -52,6 +52,7 @@ from google.auth.exceptions import MutualTLSChannelError from google.longrunning import operations_pb2 # type: ignore from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore from google.ads.admanager_v1.services.custom_field_service import ( CustomFieldServiceClient, @@ -1426,96 +1427,2324 @@ def test_list_custom_fields_rest_pager(transport: str = "rest"): assert page_.raw_page.next_page_token == token -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.CustomFieldServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): +def test_create_custom_field_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = CustomFieldServiceClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="rest", ) - # It is an error to provide a credentials file and a transport instance. + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.create_custom_field in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.create_custom_field + ] = mock_rpc + + request = {} + client.create_custom_field(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.create_custom_field(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_custom_field_rest_required_fields( + request_type=custom_field_service.CreateCustomFieldRequest, +): + transport_class = transports.CustomFieldServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_custom_field._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_custom_field._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = custom_field_messages.CustomField() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = custom_field_messages.CustomField.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.create_custom_field(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_create_custom_field_rest_unset_required_fields(): transport = transports.CustomFieldServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_custom_field._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "customField", + ) + ) + ) + + +def test_create_custom_field_rest_flattened(): + client = CustomFieldServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = CustomFieldServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = custom_field_messages.CustomField() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + custom_field=custom_field_messages.CustomField(name="name_value"), ) + mock_args.update(sample_request) - # It is an error to provide an api_key and a transport instance. - transport = transports.CustomFieldServiceRestTransport( + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = custom_field_messages.CustomField.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.create_custom_field(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/customFields" % client.transport._host, args[1] + ) + + +def test_create_custom_field_rest_flattened_error(transport: str = "rest"): + client = CustomFieldServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) - options = client_options.ClientOptions() - options.api_key = "api_key" + + # Attempting to call a method with both a request object and flattened + # fields is an error. with pytest.raises(ValueError): - client = CustomFieldServiceClient( - client_options=options, - transport=transport, + client.create_custom_field( + custom_field_service.CreateCustomFieldRequest(), + parent="parent_value", + custom_field=custom_field_messages.CustomField(name="name_value"), ) - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): + +def test_batch_create_custom_fields_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = CustomFieldServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_create_custom_fields + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_create_custom_fields + ] = mock_rpc + + request = {} + client.batch_create_custom_fields(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_create_custom_fields(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_create_custom_fields_rest_required_fields( + request_type=custom_field_service.BatchCreateCustomFieldsRequest, +): + transport_class = transports.CustomFieldServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_create_custom_fields._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_create_custom_fields._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = custom_field_service.BatchCreateCustomFieldsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = custom_field_service.BatchCreateCustomFieldsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_create_custom_fields(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_create_custom_fields_rest_unset_required_fields(): + transport = transports.CustomFieldServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_create_custom_fields._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "requests", + ) + ) + ) + + +def test_batch_create_custom_fields_rest_flattened(): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = custom_field_service.BatchCreateCustomFieldsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + requests=[ + custom_field_service.CreateCustomFieldRequest(parent="parent_value") + ], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = custom_field_service.BatchCreateCustomFieldsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.batch_create_custom_fields(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/customFields:batchCreate" + % client.transport._host, + args[1], + ) + + +def test_batch_create_custom_fields_rest_flattened_error(transport: str = "rest"): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_create_custom_fields( + custom_field_service.BatchCreateCustomFieldsRequest(), + parent="parent_value", + requests=[ + custom_field_service.CreateCustomFieldRequest(parent="parent_value") + ], + ) + + +def test_update_custom_field_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.update_custom_field in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.update_custom_field + ] = mock_rpc + + request = {} + client.update_custom_field(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_custom_field(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_update_custom_field_rest_required_fields( + request_type=custom_field_service.UpdateCustomFieldRequest, +): + transport_class = transports.CustomFieldServiceRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_custom_field._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_custom_field._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = custom_field_messages.CustomField() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = custom_field_messages.CustomField.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.update_custom_field(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_custom_field_rest_unset_required_fields(): + transport = transports.CustomFieldServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_custom_field._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("updateMask",)) + & set( + ( + "customField", + "updateMask", + ) + ) + ) + + +def test_update_custom_field_rest_flattened(): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = custom_field_messages.CustomField() + + # get arguments that satisfy an http rule for this method + sample_request = { + "custom_field": {"name": "networks/sample1/customFields/sample2"} + } + + # get truthy value for each flattened field + mock_args = dict( + custom_field=custom_field_messages.CustomField(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = custom_field_messages.CustomField.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.update_custom_field(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{custom_field.name=networks/*/customFields/*}" + % client.transport._host, + args[1], + ) + + +def test_update_custom_field_rest_flattened_error(transport: str = "rest"): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_custom_field( + custom_field_service.UpdateCustomFieldRequest(), + custom_field=custom_field_messages.CustomField(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_batch_update_custom_fields_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_update_custom_fields + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_update_custom_fields + ] = mock_rpc + + request = {} + client.batch_update_custom_fields(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_update_custom_fields(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_update_custom_fields_rest_required_fields( + request_type=custom_field_service.BatchUpdateCustomFieldsRequest, +): + transport_class = transports.CustomFieldServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_update_custom_fields._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_update_custom_fields._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = custom_field_service.BatchUpdateCustomFieldsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = custom_field_service.BatchUpdateCustomFieldsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_update_custom_fields(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_update_custom_fields_rest_unset_required_fields(): + transport = transports.CustomFieldServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_update_custom_fields._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "requests", + ) + ) + ) + + +def test_batch_update_custom_fields_rest_flattened(): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = custom_field_service.BatchUpdateCustomFieldsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + requests=[ + custom_field_service.UpdateCustomFieldRequest( + custom_field=custom_field_messages.CustomField(name="name_value") + ) + ], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = custom_field_service.BatchUpdateCustomFieldsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.batch_update_custom_fields(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/customFields:batchUpdate" + % client.transport._host, + args[1], + ) + + +def test_batch_update_custom_fields_rest_flattened_error(transport: str = "rest"): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_update_custom_fields( + custom_field_service.BatchUpdateCustomFieldsRequest(), + parent="parent_value", + requests=[ + custom_field_service.UpdateCustomFieldRequest( + custom_field=custom_field_messages.CustomField(name="name_value") + ) + ], + ) + + +def test_batch_activate_custom_fields_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_activate_custom_fields + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_activate_custom_fields + ] = mock_rpc + + request = {} + client.batch_activate_custom_fields(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_activate_custom_fields(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_activate_custom_fields_rest_required_fields( + request_type=custom_field_service.BatchActivateCustomFieldsRequest, +): + transport_class = transports.CustomFieldServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["names"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_activate_custom_fields._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + jsonified_request["names"] = "names_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_activate_custom_fields._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "names" in jsonified_request + assert jsonified_request["names"] == "names_value" + + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = custom_field_service.BatchActivateCustomFieldsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = custom_field_service.BatchActivateCustomFieldsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_activate_custom_fields(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_activate_custom_fields_rest_unset_required_fields(): + transport = transports.CustomFieldServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_activate_custom_fields._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "names", + ) + ) + ) + + +def test_batch_activate_custom_fields_rest_flattened(): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = custom_field_service.BatchActivateCustomFieldsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + names=["names_value"], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = custom_field_service.BatchActivateCustomFieldsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.batch_activate_custom_fields(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/customFields:batchActivate" + % client.transport._host, + args[1], + ) + + +def test_batch_activate_custom_fields_rest_flattened_error(transport: str = "rest"): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_activate_custom_fields( + custom_field_service.BatchActivateCustomFieldsRequest(), + parent="parent_value", + names=["names_value"], + ) + + +def test_batch_deactivate_custom_fields_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_deactivate_custom_fields + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_deactivate_custom_fields + ] = mock_rpc + + request = {} + client.batch_deactivate_custom_fields(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_deactivate_custom_fields(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_deactivate_custom_fields_rest_required_fields( + request_type=custom_field_service.BatchDeactivateCustomFieldsRequest, +): + transport_class = transports.CustomFieldServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["names"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_deactivate_custom_fields._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + jsonified_request["names"] = "names_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_deactivate_custom_fields._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "names" in jsonified_request + assert jsonified_request["names"] == "names_value" + + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = custom_field_service.BatchDeactivateCustomFieldsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = custom_field_service.BatchDeactivateCustomFieldsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_deactivate_custom_fields(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_deactivate_custom_fields_rest_unset_required_fields(): + transport = transports.CustomFieldServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_deactivate_custom_fields._get_unset_required_fields( + {} + ) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "names", + ) + ) + ) + + +def test_batch_deactivate_custom_fields_rest_flattened(): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = custom_field_service.BatchDeactivateCustomFieldsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + names=["names_value"], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = custom_field_service.BatchDeactivateCustomFieldsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.batch_deactivate_custom_fields(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/customFields:batchDeactivate" + % client.transport._host, + args[1], + ) + + +def test_batch_deactivate_custom_fields_rest_flattened_error(transport: str = "rest"): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_deactivate_custom_fields( + custom_field_service.BatchDeactivateCustomFieldsRequest(), + parent="parent_value", + names=["names_value"], + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.CustomFieldServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.CustomFieldServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CustomFieldServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.CustomFieldServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CustomFieldServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CustomFieldServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.CustomFieldServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CustomFieldServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.CustomFieldServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = CustomFieldServiceClient(transport=transport) + assert client.transport is transport + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CustomFieldServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_rest(): + transport = CustomFieldServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_custom_field_rest_bad_request( + request_type=custom_field_service.GetCustomFieldRequest, +): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/customFields/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_custom_field(request) + + +@pytest.mark.parametrize( + "request_type", + [ + custom_field_service.GetCustomFieldRequest, + dict, + ], +) +def test_get_custom_field_rest_call_success(request_type): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/customFields/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = custom_field_messages.CustomField( + name="name_value", + custom_field_id=1578, + display_name="display_name_value", + description="description_value", + status=custom_field_enums.CustomFieldStatusEnum.CustomFieldStatus.ACTIVE, + entity_type=custom_field_enums.CustomFieldEntityTypeEnum.CustomFieldEntityType.LINE_ITEM, + data_type=custom_field_enums.CustomFieldDataTypeEnum.CustomFieldDataType.STRING, + visibility=custom_field_enums.CustomFieldVisibilityEnum.CustomFieldVisibility.HIDDEN, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = custom_field_messages.CustomField.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_custom_field(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, custom_field_messages.CustomField) + assert response.name == "name_value" + assert response.custom_field_id == 1578 + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert ( + response.status + == custom_field_enums.CustomFieldStatusEnum.CustomFieldStatus.ACTIVE + ) + assert ( + response.entity_type + == custom_field_enums.CustomFieldEntityTypeEnum.CustomFieldEntityType.LINE_ITEM + ) + assert ( + response.data_type + == custom_field_enums.CustomFieldDataTypeEnum.CustomFieldDataType.STRING + ) + assert ( + response.visibility + == custom_field_enums.CustomFieldVisibilityEnum.CustomFieldVisibility.HIDDEN + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_custom_field_rest_interceptors(null_interceptor): + transport = transports.CustomFieldServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.CustomFieldServiceRestInterceptor(), + ) + client = CustomFieldServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.CustomFieldServiceRestInterceptor, "post_get_custom_field" + ) as post, mock.patch.object( + transports.CustomFieldServiceRestInterceptor, + "post_get_custom_field_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.CustomFieldServiceRestInterceptor, "pre_get_custom_field" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = custom_field_service.GetCustomFieldRequest.pb( + custom_field_service.GetCustomFieldRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = custom_field_messages.CustomField.to_json( + custom_field_messages.CustomField() + ) + req.return_value.content = return_value + + request = custom_field_service.GetCustomFieldRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = custom_field_messages.CustomField() + post_with_metadata.return_value = custom_field_messages.CustomField(), metadata + + client.get_custom_field( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_custom_fields_rest_bad_request( + request_type=custom_field_service.ListCustomFieldsRequest, +): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_custom_fields(request) + + +@pytest.mark.parametrize( + "request_type", + [ + custom_field_service.ListCustomFieldsRequest, + dict, + ], +) +def test_list_custom_fields_rest_call_success(request_type): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = custom_field_service.ListCustomFieldsResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = custom_field_service.ListCustomFieldsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_custom_fields(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListCustomFieldsPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_custom_fields_rest_interceptors(null_interceptor): + transport = transports.CustomFieldServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.CustomFieldServiceRestInterceptor(), + ) + client = CustomFieldServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.CustomFieldServiceRestInterceptor, "post_list_custom_fields" + ) as post, mock.patch.object( + transports.CustomFieldServiceRestInterceptor, + "post_list_custom_fields_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.CustomFieldServiceRestInterceptor, "pre_list_custom_fields" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = custom_field_service.ListCustomFieldsRequest.pb( + custom_field_service.ListCustomFieldsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = custom_field_service.ListCustomFieldsResponse.to_json( + custom_field_service.ListCustomFieldsResponse() + ) + req.return_value.content = return_value + + request = custom_field_service.ListCustomFieldsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = custom_field_service.ListCustomFieldsResponse() + post_with_metadata.return_value = ( + custom_field_service.ListCustomFieldsResponse(), + metadata, + ) + + client.list_custom_fields( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_create_custom_field_rest_bad_request( + request_type=custom_field_service.CreateCustomFieldRequest, +): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.create_custom_field(request) + + +@pytest.mark.parametrize( + "request_type", + [ + custom_field_service.CreateCustomFieldRequest, + dict, + ], +) +def test_create_custom_field_rest_call_success(request_type): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request_init["custom_field"] = { + "name": "name_value", + "custom_field_id": 1578, + "display_name": "display_name_value", + "description": "description_value", + "status": 1, + "entity_type": 1, + "data_type": 1, + "visibility": 1, + "options": [ + {"custom_field_option_id": 2338, "display_name": "display_name_value"} + ], + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = custom_field_service.CreateCustomFieldRequest.meta.fields[ + "custom_field" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["custom_field"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["custom_field"][field])): + del request_init["custom_field"][field][i][subfield] + else: + del request_init["custom_field"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = custom_field_messages.CustomField( + name="name_value", + custom_field_id=1578, + display_name="display_name_value", + description="description_value", + status=custom_field_enums.CustomFieldStatusEnum.CustomFieldStatus.ACTIVE, + entity_type=custom_field_enums.CustomFieldEntityTypeEnum.CustomFieldEntityType.LINE_ITEM, + data_type=custom_field_enums.CustomFieldDataTypeEnum.CustomFieldDataType.STRING, + visibility=custom_field_enums.CustomFieldVisibilityEnum.CustomFieldVisibility.HIDDEN, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = custom_field_messages.CustomField.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.create_custom_field(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, custom_field_messages.CustomField) + assert response.name == "name_value" + assert response.custom_field_id == 1578 + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert ( + response.status + == custom_field_enums.CustomFieldStatusEnum.CustomFieldStatus.ACTIVE + ) + assert ( + response.entity_type + == custom_field_enums.CustomFieldEntityTypeEnum.CustomFieldEntityType.LINE_ITEM + ) + assert ( + response.data_type + == custom_field_enums.CustomFieldDataTypeEnum.CustomFieldDataType.STRING + ) + assert ( + response.visibility + == custom_field_enums.CustomFieldVisibilityEnum.CustomFieldVisibility.HIDDEN + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_custom_field_rest_interceptors(null_interceptor): + transport = transports.CustomFieldServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.CustomFieldServiceRestInterceptor(), + ) + client = CustomFieldServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.CustomFieldServiceRestInterceptor, "post_create_custom_field" + ) as post, mock.patch.object( + transports.CustomFieldServiceRestInterceptor, + "post_create_custom_field_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.CustomFieldServiceRestInterceptor, "pre_create_custom_field" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = custom_field_service.CreateCustomFieldRequest.pb( + custom_field_service.CreateCustomFieldRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = custom_field_messages.CustomField.to_json( + custom_field_messages.CustomField() + ) + req.return_value.content = return_value + + request = custom_field_service.CreateCustomFieldRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = custom_field_messages.CustomField() + post_with_metadata.return_value = custom_field_messages.CustomField(), metadata + + client.create_custom_field( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_batch_create_custom_fields_rest_bad_request( + request_type=custom_field_service.BatchCreateCustomFieldsRequest, +): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.batch_create_custom_fields(request) + + +@pytest.mark.parametrize( + "request_type", + [ + custom_field_service.BatchCreateCustomFieldsRequest, + dict, + ], +) +def test_batch_create_custom_fields_rest_call_success(request_type): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = custom_field_service.BatchCreateCustomFieldsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = custom_field_service.BatchCreateCustomFieldsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.batch_create_custom_fields(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, custom_field_service.BatchCreateCustomFieldsResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_create_custom_fields_rest_interceptors(null_interceptor): + transport = transports.CustomFieldServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.CustomFieldServiceRestInterceptor(), + ) + client = CustomFieldServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.CustomFieldServiceRestInterceptor, "post_batch_create_custom_fields" + ) as post, mock.patch.object( + transports.CustomFieldServiceRestInterceptor, + "post_batch_create_custom_fields_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.CustomFieldServiceRestInterceptor, "pre_batch_create_custom_fields" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = custom_field_service.BatchCreateCustomFieldsRequest.pb( + custom_field_service.BatchCreateCustomFieldsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = custom_field_service.BatchCreateCustomFieldsResponse.to_json( + custom_field_service.BatchCreateCustomFieldsResponse() + ) + req.return_value.content = return_value + + request = custom_field_service.BatchCreateCustomFieldsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = custom_field_service.BatchCreateCustomFieldsResponse() + post_with_metadata.return_value = ( + custom_field_service.BatchCreateCustomFieldsResponse(), + metadata, + ) + + client.batch_create_custom_fields( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_update_custom_field_rest_bad_request( + request_type=custom_field_service.UpdateCustomFieldRequest, +): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"custom_field": {"name": "networks/sample1/customFields/sample2"}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.update_custom_field(request) + + +@pytest.mark.parametrize( + "request_type", + [ + custom_field_service.UpdateCustomFieldRequest, + dict, + ], +) +def test_update_custom_field_rest_call_success(request_type): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"custom_field": {"name": "networks/sample1/customFields/sample2"}} + request_init["custom_field"] = { + "name": "networks/sample1/customFields/sample2", + "custom_field_id": 1578, + "display_name": "display_name_value", + "description": "description_value", + "status": 1, + "entity_type": 1, + "data_type": 1, + "visibility": 1, + "options": [ + {"custom_field_option_id": 2338, "display_name": "display_name_value"} + ], + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = custom_field_service.UpdateCustomFieldRequest.meta.fields[ + "custom_field" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["custom_field"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["custom_field"][field])): + del request_init["custom_field"][field][i][subfield] + else: + del request_init["custom_field"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = custom_field_messages.CustomField( + name="name_value", + custom_field_id=1578, + display_name="display_name_value", + description="description_value", + status=custom_field_enums.CustomFieldStatusEnum.CustomFieldStatus.ACTIVE, + entity_type=custom_field_enums.CustomFieldEntityTypeEnum.CustomFieldEntityType.LINE_ITEM, + data_type=custom_field_enums.CustomFieldDataTypeEnum.CustomFieldDataType.STRING, + visibility=custom_field_enums.CustomFieldVisibilityEnum.CustomFieldVisibility.HIDDEN, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = custom_field_messages.CustomField.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.update_custom_field(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, custom_field_messages.CustomField) + assert response.name == "name_value" + assert response.custom_field_id == 1578 + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert ( + response.status + == custom_field_enums.CustomFieldStatusEnum.CustomFieldStatus.ACTIVE + ) + assert ( + response.entity_type + == custom_field_enums.CustomFieldEntityTypeEnum.CustomFieldEntityType.LINE_ITEM + ) + assert ( + response.data_type + == custom_field_enums.CustomFieldDataTypeEnum.CustomFieldDataType.STRING + ) + assert ( + response.visibility + == custom_field_enums.CustomFieldVisibilityEnum.CustomFieldVisibility.HIDDEN + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_custom_field_rest_interceptors(null_interceptor): + transport = transports.CustomFieldServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.CustomFieldServiceRestInterceptor(), + ) + client = CustomFieldServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.CustomFieldServiceRestInterceptor, "post_update_custom_field" + ) as post, mock.patch.object( + transports.CustomFieldServiceRestInterceptor, + "post_update_custom_field_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.CustomFieldServiceRestInterceptor, "pre_update_custom_field" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = custom_field_service.UpdateCustomFieldRequest.pb( + custom_field_service.UpdateCustomFieldRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = custom_field_messages.CustomField.to_json( + custom_field_messages.CustomField() + ) + req.return_value.content = return_value + + request = custom_field_service.UpdateCustomFieldRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = custom_field_messages.CustomField() + post_with_metadata.return_value = custom_field_messages.CustomField(), metadata + + client.update_custom_field( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_batch_update_custom_fields_rest_bad_request( + request_type=custom_field_service.BatchUpdateCustomFieldsRequest, +): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.batch_update_custom_fields(request) + + +@pytest.mark.parametrize( + "request_type", + [ + custom_field_service.BatchUpdateCustomFieldsRequest, + dict, + ], +) +def test_batch_update_custom_fields_rest_call_success(request_type): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = custom_field_service.BatchUpdateCustomFieldsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = custom_field_service.BatchUpdateCustomFieldsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.batch_update_custom_fields(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, custom_field_service.BatchUpdateCustomFieldsResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_update_custom_fields_rest_interceptors(null_interceptor): + transport = transports.CustomFieldServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.CustomFieldServiceRestInterceptor(), + ) + client = CustomFieldServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.CustomFieldServiceRestInterceptor, "post_batch_update_custom_fields" + ) as post, mock.patch.object( + transports.CustomFieldServiceRestInterceptor, + "post_batch_update_custom_fields_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.CustomFieldServiceRestInterceptor, "pre_batch_update_custom_fields" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = custom_field_service.BatchUpdateCustomFieldsRequest.pb( + custom_field_service.BatchUpdateCustomFieldsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = custom_field_service.BatchUpdateCustomFieldsResponse.to_json( + custom_field_service.BatchUpdateCustomFieldsResponse() ) + req.return_value.content = return_value - # It is an error to provide scopes and a transport instance. - transport = transports.CustomFieldServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = CustomFieldServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, + request = custom_field_service.BatchUpdateCustomFieldsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = custom_field_service.BatchUpdateCustomFieldsResponse() + post_with_metadata.return_value = ( + custom_field_service.BatchUpdateCustomFieldsResponse(), + metadata, ) + client.batch_update_custom_fields( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.CustomFieldServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - client = CustomFieldServiceClient(transport=transport) - assert client.transport is transport - - -@pytest.mark.parametrize( - "transport_class", - [ - transports.CustomFieldServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() - - -def test_transport_kind_rest(): - transport = CustomFieldServiceClient.get_transport_class("rest")( - credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "rest" + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() -def test_get_custom_field_rest_bad_request( - request_type=custom_field_service.GetCustomFieldRequest, +def test_batch_activate_custom_fields_rest_bad_request( + request_type=custom_field_service.BatchActivateCustomFieldsRequest, ): client = CustomFieldServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "networks/sample1/customFields/sample2"} + request_init = {"parent": "networks/sample1"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -1530,77 +3759,50 @@ def test_get_custom_field_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_custom_field(request) + client.batch_activate_custom_fields(request) @pytest.mark.parametrize( "request_type", [ - custom_field_service.GetCustomFieldRequest, + custom_field_service.BatchActivateCustomFieldsRequest, dict, ], ) -def test_get_custom_field_rest_call_success(request_type): +def test_batch_activate_custom_fields_rest_call_success(request_type): client = CustomFieldServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "networks/sample1/customFields/sample2"} + request_init = {"parent": "networks/sample1"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = custom_field_messages.CustomField( - name="name_value", - custom_field_id=1578, - display_name="display_name_value", - description="description_value", - status=custom_field_enums.CustomFieldStatusEnum.CustomFieldStatus.ACTIVE, - entity_type=custom_field_enums.CustomFieldEntityTypeEnum.CustomFieldEntityType.LINE_ITEM, - data_type=custom_field_enums.CustomFieldDataTypeEnum.CustomFieldDataType.STRING, - visibility=custom_field_enums.CustomFieldVisibilityEnum.CustomFieldVisibility.HIDDEN, - ) + return_value = custom_field_service.BatchActivateCustomFieldsResponse() # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 # Convert return value to protobuf type - return_value = custom_field_messages.CustomField.pb(return_value) + return_value = custom_field_service.BatchActivateCustomFieldsResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_custom_field(request) + response = client.batch_activate_custom_fields(request) # Establish that the response is the type that we expect. - assert isinstance(response, custom_field_messages.CustomField) - assert response.name == "name_value" - assert response.custom_field_id == 1578 - assert response.display_name == "display_name_value" - assert response.description == "description_value" - assert ( - response.status - == custom_field_enums.CustomFieldStatusEnum.CustomFieldStatus.ACTIVE - ) - assert ( - response.entity_type - == custom_field_enums.CustomFieldEntityTypeEnum.CustomFieldEntityType.LINE_ITEM - ) - assert ( - response.data_type - == custom_field_enums.CustomFieldDataTypeEnum.CustomFieldDataType.STRING - ) - assert ( - response.visibility - == custom_field_enums.CustomFieldVisibilityEnum.CustomFieldVisibility.HIDDEN - ) + assert isinstance(response, custom_field_service.BatchActivateCustomFieldsResponse) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_custom_field_rest_interceptors(null_interceptor): +def test_batch_activate_custom_fields_rest_interceptors(null_interceptor): transport = transports.CustomFieldServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -1614,18 +3816,19 @@ def test_get_custom_field_rest_interceptors(null_interceptor): ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.CustomFieldServiceRestInterceptor, "post_get_custom_field" + transports.CustomFieldServiceRestInterceptor, + "post_batch_activate_custom_fields", ) as post, mock.patch.object( transports.CustomFieldServiceRestInterceptor, - "post_get_custom_field_with_metadata", + "post_batch_activate_custom_fields_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.CustomFieldServiceRestInterceptor, "pre_get_custom_field" + transports.CustomFieldServiceRestInterceptor, "pre_batch_activate_custom_fields" ) as pre: pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = custom_field_service.GetCustomFieldRequest.pb( - custom_field_service.GetCustomFieldRequest() + pb_message = custom_field_service.BatchActivateCustomFieldsRequest.pb( + custom_field_service.BatchActivateCustomFieldsRequest() ) transcode.return_value = { "method": "post", @@ -1637,21 +3840,24 @@ def test_get_custom_field_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = custom_field_messages.CustomField.to_json( - custom_field_messages.CustomField() + return_value = custom_field_service.BatchActivateCustomFieldsResponse.to_json( + custom_field_service.BatchActivateCustomFieldsResponse() ) req.return_value.content = return_value - request = custom_field_service.GetCustomFieldRequest() + request = custom_field_service.BatchActivateCustomFieldsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = custom_field_messages.CustomField() - post_with_metadata.return_value = custom_field_messages.CustomField(), metadata + post.return_value = custom_field_service.BatchActivateCustomFieldsResponse() + post_with_metadata.return_value = ( + custom_field_service.BatchActivateCustomFieldsResponse(), + metadata, + ) - client.get_custom_field( + client.batch_activate_custom_fields( request, metadata=[ ("key", "val"), @@ -1664,8 +3870,8 @@ def test_get_custom_field_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_custom_fields_rest_bad_request( - request_type=custom_field_service.ListCustomFieldsRequest, +def test_batch_deactivate_custom_fields_rest_bad_request( + request_type=custom_field_service.BatchDeactivateCustomFieldsRequest, ): client = CustomFieldServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -1686,17 +3892,17 @@ def test_list_custom_fields_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_custom_fields(request) + client.batch_deactivate_custom_fields(request) @pytest.mark.parametrize( "request_type", [ - custom_field_service.ListCustomFieldsRequest, + custom_field_service.BatchDeactivateCustomFieldsRequest, dict, ], ) -def test_list_custom_fields_rest_call_success(request_type): +def test_batch_deactivate_custom_fields_rest_call_success(request_type): client = CustomFieldServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -1708,31 +3914,30 @@ def test_list_custom_fields_rest_call_success(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = custom_field_service.ListCustomFieldsResponse( - next_page_token="next_page_token_value", - total_size=1086, - ) + return_value = custom_field_service.BatchDeactivateCustomFieldsResponse() # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 # Convert return value to protobuf type - return_value = custom_field_service.ListCustomFieldsResponse.pb(return_value) + return_value = custom_field_service.BatchDeactivateCustomFieldsResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_custom_fields(request) + response = client.batch_deactivate_custom_fields(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListCustomFieldsPager) - assert response.next_page_token == "next_page_token_value" - assert response.total_size == 1086 + assert isinstance( + response, custom_field_service.BatchDeactivateCustomFieldsResponse + ) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_custom_fields_rest_interceptors(null_interceptor): +def test_batch_deactivate_custom_fields_rest_interceptors(null_interceptor): transport = transports.CustomFieldServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -1746,18 +3951,20 @@ def test_list_custom_fields_rest_interceptors(null_interceptor): ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.CustomFieldServiceRestInterceptor, "post_list_custom_fields" + transports.CustomFieldServiceRestInterceptor, + "post_batch_deactivate_custom_fields", ) as post, mock.patch.object( transports.CustomFieldServiceRestInterceptor, - "post_list_custom_fields_with_metadata", + "post_batch_deactivate_custom_fields_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.CustomFieldServiceRestInterceptor, "pre_list_custom_fields" + transports.CustomFieldServiceRestInterceptor, + "pre_batch_deactivate_custom_fields", ) as pre: pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = custom_field_service.ListCustomFieldsRequest.pb( - custom_field_service.ListCustomFieldsRequest() + pb_message = custom_field_service.BatchDeactivateCustomFieldsRequest.pb( + custom_field_service.BatchDeactivateCustomFieldsRequest() ) transcode.return_value = { "method": "post", @@ -1769,24 +3976,24 @@ def test_list_custom_fields_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = custom_field_service.ListCustomFieldsResponse.to_json( - custom_field_service.ListCustomFieldsResponse() + return_value = custom_field_service.BatchDeactivateCustomFieldsResponse.to_json( + custom_field_service.BatchDeactivateCustomFieldsResponse() ) req.return_value.content = return_value - request = custom_field_service.ListCustomFieldsRequest() + request = custom_field_service.BatchDeactivateCustomFieldsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = custom_field_service.ListCustomFieldsResponse() + post.return_value = custom_field_service.BatchDeactivateCustomFieldsResponse() post_with_metadata.return_value = ( - custom_field_service.ListCustomFieldsResponse(), + custom_field_service.BatchDeactivateCustomFieldsResponse(), metadata, ) - client.list_custom_fields( + client.batch_deactivate_custom_fields( request, metadata=[ ("key", "val"), @@ -1910,6 +4117,138 @@ def test_list_custom_fields_empty_call_rest(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_custom_field_empty_call_rest(): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_custom_field), "__call__" + ) as call: + client.create_custom_field(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = custom_field_service.CreateCustomFieldRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_create_custom_fields_empty_call_rest(): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_custom_fields), "__call__" + ) as call: + client.batch_create_custom_fields(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = custom_field_service.BatchCreateCustomFieldsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_custom_field_empty_call_rest(): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.update_custom_field), "__call__" + ) as call: + client.update_custom_field(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = custom_field_service.UpdateCustomFieldRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_update_custom_fields_empty_call_rest(): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_update_custom_fields), "__call__" + ) as call: + client.batch_update_custom_fields(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = custom_field_service.BatchUpdateCustomFieldsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_activate_custom_fields_empty_call_rest(): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_activate_custom_fields), "__call__" + ) as call: + client.batch_activate_custom_fields(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = custom_field_service.BatchActivateCustomFieldsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_deactivate_custom_fields_empty_call_rest(): + client = CustomFieldServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_deactivate_custom_fields), "__call__" + ) as call: + client.batch_deactivate_custom_fields(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = custom_field_service.BatchDeactivateCustomFieldsRequest() + + assert args[0] == request_msg + + def test_custom_field_service_base_transport_error(): # Passing both a credentials object and credentials_file should raise an error with pytest.raises(core_exceptions.DuplicateCredentialArgs): @@ -1934,6 +4273,12 @@ def test_custom_field_service_base_transport(): methods = ( "get_custom_field", "list_custom_fields", + "create_custom_field", + "batch_create_custom_fields", + "update_custom_field", + "batch_update_custom_fields", + "batch_activate_custom_fields", + "batch_deactivate_custom_fields", "get_operation", ) for method in methods: @@ -2072,6 +4417,24 @@ def test_custom_field_service_client_transport_session_collision(transport_name) session1 = client1.transport.list_custom_fields._session session2 = client2.transport.list_custom_fields._session assert session1 != session2 + session1 = client1.transport.create_custom_field._session + session2 = client2.transport.create_custom_field._session + assert session1 != session2 + session1 = client1.transport.batch_create_custom_fields._session + session2 = client2.transport.batch_create_custom_fields._session + assert session1 != session2 + session1 = client1.transport.update_custom_field._session + session2 = client2.transport.update_custom_field._session + assert session1 != session2 + session1 = client1.transport.batch_update_custom_fields._session + session2 = client2.transport.batch_update_custom_fields._session + assert session1 != session2 + session1 = client1.transport.batch_activate_custom_fields._session + session2 = client2.transport.batch_activate_custom_fields._session + assert session1 != session2 + session1 = client1.transport.batch_deactivate_custom_fields._session + session2 = client2.transport.batch_deactivate_custom_fields._session + assert session1 != session2 def test_custom_field_path(): diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_device_capability_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_device_capability_service.py new file mode 100644 index 000000000000..c8052c6afbf2 --- /dev/null +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_device_capability_service.py @@ -0,0 +1,2317 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account + +from google.ads.admanager_v1.services.device_capability_service import ( + DeviceCapabilityServiceClient, + pagers, + transports, +) +from google.ads.admanager_v1.types import ( + device_capability_messages, + device_capability_service, +) + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert DeviceCapabilityServiceClient._get_default_mtls_endpoint(None) is None + assert ( + DeviceCapabilityServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + DeviceCapabilityServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + DeviceCapabilityServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + DeviceCapabilityServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + DeviceCapabilityServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +def test__read_environment_variables(): + assert DeviceCapabilityServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert DeviceCapabilityServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert DeviceCapabilityServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + DeviceCapabilityServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert DeviceCapabilityServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert DeviceCapabilityServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert DeviceCapabilityServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + DeviceCapabilityServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert DeviceCapabilityServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert DeviceCapabilityServiceClient._get_client_cert_source(None, False) is None + assert ( + DeviceCapabilityServiceClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + DeviceCapabilityServiceClient._get_client_cert_source( + mock_provided_cert_source, True + ) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + DeviceCapabilityServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + DeviceCapabilityServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + DeviceCapabilityServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DeviceCapabilityServiceClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = DeviceCapabilityServiceClient._DEFAULT_UNIVERSE + default_endpoint = DeviceCapabilityServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = DeviceCapabilityServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + DeviceCapabilityServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + DeviceCapabilityServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == DeviceCapabilityServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + DeviceCapabilityServiceClient._get_api_endpoint( + None, None, default_universe, "auto" + ) + == default_endpoint + ) + assert ( + DeviceCapabilityServiceClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == DeviceCapabilityServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + DeviceCapabilityServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == DeviceCapabilityServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + DeviceCapabilityServiceClient._get_api_endpoint( + None, None, mock_universe, "never" + ) + == mock_endpoint + ) + assert ( + DeviceCapabilityServiceClient._get_api_endpoint( + None, None, default_universe, "never" + ) + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + DeviceCapabilityServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + DeviceCapabilityServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + DeviceCapabilityServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + DeviceCapabilityServiceClient._get_universe_domain(None, None) + == DeviceCapabilityServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + DeviceCapabilityServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DeviceCapabilityServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DeviceCapabilityServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (DeviceCapabilityServiceClient, "rest"), + ], +) +def test_device_capability_service_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.DeviceCapabilityServiceRestTransport, "rest"), + ], +) +def test_device_capability_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (DeviceCapabilityServiceClient, "rest"), + ], +) +def test_device_capability_service_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +def test_device_capability_service_client_get_transport_class(): + transport = DeviceCapabilityServiceClient.get_transport_class() + available_transports = [ + transports.DeviceCapabilityServiceRestTransport, + ] + assert transport in available_transports + + transport = DeviceCapabilityServiceClient.get_transport_class("rest") + assert transport == transports.DeviceCapabilityServiceRestTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + DeviceCapabilityServiceClient, + transports.DeviceCapabilityServiceRestTransport, + "rest", + ), + ], +) +@mock.patch.object( + DeviceCapabilityServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DeviceCapabilityServiceClient), +) +def test_device_capability_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(DeviceCapabilityServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(DeviceCapabilityServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + DeviceCapabilityServiceClient, + transports.DeviceCapabilityServiceRestTransport, + "rest", + "true", + ), + ( + DeviceCapabilityServiceClient, + transports.DeviceCapabilityServiceRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + DeviceCapabilityServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DeviceCapabilityServiceClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_device_capability_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [DeviceCapabilityServiceClient]) +@mock.patch.object( + DeviceCapabilityServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(DeviceCapabilityServiceClient), +) +def test_device_capability_service_client_get_mtls_endpoint_and_cert_source( + client_class, +): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize("client_class", [DeviceCapabilityServiceClient]) +@mock.patch.object( + DeviceCapabilityServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DeviceCapabilityServiceClient), +) +def test_device_capability_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = DeviceCapabilityServiceClient._DEFAULT_UNIVERSE + default_endpoint = DeviceCapabilityServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = DeviceCapabilityServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + DeviceCapabilityServiceClient, + transports.DeviceCapabilityServiceRestTransport, + "rest", + ), + ], +) +def test_device_capability_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + DeviceCapabilityServiceClient, + transports.DeviceCapabilityServiceRestTransport, + "rest", + None, + ), + ], +) +def test_device_capability_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_get_device_capability_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_device_capability + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_device_capability + ] = mock_rpc + + request = {} + client.get_device_capability(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_device_capability(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_device_capability_rest_required_fields( + request_type=device_capability_service.GetDeviceCapabilityRequest, +): + transport_class = transports.DeviceCapabilityServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_device_capability._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_device_capability._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = device_capability_messages.DeviceCapability() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = device_capability_messages.DeviceCapability.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_device_capability(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_device_capability_rest_unset_required_fields(): + transport = transports.DeviceCapabilityServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_device_capability._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_device_capability_rest_flattened(): + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = device_capability_messages.DeviceCapability() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "networks/sample1/deviceCapabilities/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = device_capability_messages.DeviceCapability.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_device_capability(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=networks/*/deviceCapabilities/*}" % client.transport._host, + args[1], + ) + + +def test_get_device_capability_rest_flattened_error(transport: str = "rest"): + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_device_capability( + device_capability_service.GetDeviceCapabilityRequest(), + name="name_value", + ) + + +def test_list_device_capabilities_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_device_capabilities + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_device_capabilities + ] = mock_rpc + + request = {} + client.list_device_capabilities(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_device_capabilities(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_device_capabilities_rest_required_fields( + request_type=device_capability_service.ListDeviceCapabilitiesRequest, +): + transport_class = transports.DeviceCapabilityServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_device_capabilities._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_device_capabilities._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + "skip", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = device_capability_service.ListDeviceCapabilitiesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = device_capability_service.ListDeviceCapabilitiesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_device_capabilities(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_device_capabilities_rest_unset_required_fields(): + transport = transports.DeviceCapabilityServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_device_capabilities._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + "skip", + ) + ) + & set(("parent",)) + ) + + +def test_list_device_capabilities_rest_flattened(): + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = device_capability_service.ListDeviceCapabilitiesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = device_capability_service.ListDeviceCapabilitiesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_device_capabilities(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/deviceCapabilities" % client.transport._host, + args[1], + ) + + +def test_list_device_capabilities_rest_flattened_error(transport: str = "rest"): + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_device_capabilities( + device_capability_service.ListDeviceCapabilitiesRequest(), + parent="parent_value", + ) + + +def test_list_device_capabilities_rest_pager(transport: str = "rest"): + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + device_capability_service.ListDeviceCapabilitiesResponse( + device_capabilities=[ + device_capability_messages.DeviceCapability(), + device_capability_messages.DeviceCapability(), + device_capability_messages.DeviceCapability(), + ], + next_page_token="abc", + ), + device_capability_service.ListDeviceCapabilitiesResponse( + device_capabilities=[], + next_page_token="def", + ), + device_capability_service.ListDeviceCapabilitiesResponse( + device_capabilities=[ + device_capability_messages.DeviceCapability(), + ], + next_page_token="ghi", + ), + device_capability_service.ListDeviceCapabilitiesResponse( + device_capabilities=[ + device_capability_messages.DeviceCapability(), + device_capability_messages.DeviceCapability(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + device_capability_service.ListDeviceCapabilitiesResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "networks/sample1"} + + pager = client.list_device_capabilities(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, device_capability_messages.DeviceCapability) for i in results + ) + + pages = list(client.list_device_capabilities(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.DeviceCapabilityServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.DeviceCapabilityServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = DeviceCapabilityServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.DeviceCapabilityServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = DeviceCapabilityServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = DeviceCapabilityServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.DeviceCapabilityServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = DeviceCapabilityServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.DeviceCapabilityServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = DeviceCapabilityServiceClient(transport=transport) + assert client.transport is transport + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.DeviceCapabilityServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_rest(): + transport = DeviceCapabilityServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_device_capability_rest_bad_request( + request_type=device_capability_service.GetDeviceCapabilityRequest, +): + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/deviceCapabilities/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_device_capability(request) + + +@pytest.mark.parametrize( + "request_type", + [ + device_capability_service.GetDeviceCapabilityRequest, + dict, + ], +) +def test_get_device_capability_rest_call_success(request_type): + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/deviceCapabilities/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = device_capability_messages.DeviceCapability( + name="name_value", + display_name="display_name_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = device_capability_messages.DeviceCapability.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_device_capability(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, device_capability_messages.DeviceCapability) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_device_capability_rest_interceptors(null_interceptor): + transport = transports.DeviceCapabilityServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DeviceCapabilityServiceRestInterceptor(), + ) + client = DeviceCapabilityServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.DeviceCapabilityServiceRestInterceptor, "post_get_device_capability" + ) as post, mock.patch.object( + transports.DeviceCapabilityServiceRestInterceptor, + "post_get_device_capability_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.DeviceCapabilityServiceRestInterceptor, "pre_get_device_capability" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = device_capability_service.GetDeviceCapabilityRequest.pb( + device_capability_service.GetDeviceCapabilityRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = device_capability_messages.DeviceCapability.to_json( + device_capability_messages.DeviceCapability() + ) + req.return_value.content = return_value + + request = device_capability_service.GetDeviceCapabilityRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = device_capability_messages.DeviceCapability() + post_with_metadata.return_value = ( + device_capability_messages.DeviceCapability(), + metadata, + ) + + client.get_device_capability( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_device_capabilities_rest_bad_request( + request_type=device_capability_service.ListDeviceCapabilitiesRequest, +): + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_device_capabilities(request) + + +@pytest.mark.parametrize( + "request_type", + [ + device_capability_service.ListDeviceCapabilitiesRequest, + dict, + ], +) +def test_list_device_capabilities_rest_call_success(request_type): + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = device_capability_service.ListDeviceCapabilitiesResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = device_capability_service.ListDeviceCapabilitiesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_device_capabilities(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListDeviceCapabilitiesPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_device_capabilities_rest_interceptors(null_interceptor): + transport = transports.DeviceCapabilityServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DeviceCapabilityServiceRestInterceptor(), + ) + client = DeviceCapabilityServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.DeviceCapabilityServiceRestInterceptor, + "post_list_device_capabilities", + ) as post, mock.patch.object( + transports.DeviceCapabilityServiceRestInterceptor, + "post_list_device_capabilities_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.DeviceCapabilityServiceRestInterceptor, + "pre_list_device_capabilities", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = device_capability_service.ListDeviceCapabilitiesRequest.pb( + device_capability_service.ListDeviceCapabilitiesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = device_capability_service.ListDeviceCapabilitiesResponse.to_json( + device_capability_service.ListDeviceCapabilitiesResponse() + ) + req.return_value.content = return_value + + request = device_capability_service.ListDeviceCapabilitiesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = device_capability_service.ListDeviceCapabilitiesResponse() + post_with_metadata.return_value = ( + device_capability_service.ListDeviceCapabilitiesResponse(), + metadata, + ) + + client.list_device_capabilities( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "networks/sample1/operations/reports/runs/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "networks/sample1/operations/reports/runs/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_initialize_client_w_rest(): + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_device_capability_empty_call_rest(): + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_device_capability), "__call__" + ) as call: + client.get_device_capability(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = device_capability_service.GetDeviceCapabilityRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_device_capabilities_empty_call_rest(): + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_device_capabilities), "__call__" + ) as call: + client.list_device_capabilities(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = device_capability_service.ListDeviceCapabilitiesRequest() + + assert args[0] == request_msg + + +def test_device_capability_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.DeviceCapabilityServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_device_capability_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.ads.admanager_v1.services.device_capability_service.transports.DeviceCapabilityServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.DeviceCapabilityServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "get_device_capability", + "list_device_capabilities", + "get_operation", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_device_capability_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.ads.admanager_v1.services.device_capability_service.transports.DeviceCapabilityServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.DeviceCapabilityServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id="octopus", + ) + + +def test_device_capability_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.ads.admanager_v1.services.device_capability_service.transports.DeviceCapabilityServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.DeviceCapabilityServiceTransport() + adc.assert_called_once() + + +def test_device_capability_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + DeviceCapabilityServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id=None, + ) + + +def test_device_capability_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.DeviceCapabilityServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_device_capability_service_host_no_port(transport_name): + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_device_capability_service_host_with_port(transport_name): + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_device_capability_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = DeviceCapabilityServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = DeviceCapabilityServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.get_device_capability._session + session2 = client2.transport.get_device_capability._session + assert session1 != session2 + session1 = client1.transport.list_device_capabilities._session + session2 = client2.transport.list_device_capabilities._session + assert session1 != session2 + + +def test_device_capability_path(): + network_code = "squid" + device_capability = "clam" + expected = "networks/{network_code}/deviceCapabilities/{device_capability}".format( + network_code=network_code, + device_capability=device_capability, + ) + actual = DeviceCapabilityServiceClient.device_capability_path( + network_code, device_capability + ) + assert expected == actual + + +def test_parse_device_capability_path(): + expected = { + "network_code": "whelk", + "device_capability": "octopus", + } + path = DeviceCapabilityServiceClient.device_capability_path(**expected) + + # Check that the path construction is reversible. + actual = DeviceCapabilityServiceClient.parse_device_capability_path(path) + assert expected == actual + + +def test_network_path(): + network_code = "oyster" + expected = "networks/{network_code}".format( + network_code=network_code, + ) + actual = DeviceCapabilityServiceClient.network_path(network_code) + assert expected == actual + + +def test_parse_network_path(): + expected = { + "network_code": "nudibranch", + } + path = DeviceCapabilityServiceClient.network_path(**expected) + + # Check that the path construction is reversible. + actual = DeviceCapabilityServiceClient.parse_network_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = DeviceCapabilityServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = DeviceCapabilityServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = DeviceCapabilityServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = DeviceCapabilityServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = DeviceCapabilityServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = DeviceCapabilityServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = DeviceCapabilityServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = DeviceCapabilityServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = DeviceCapabilityServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format( + project=project, + ) + actual = DeviceCapabilityServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = DeviceCapabilityServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = DeviceCapabilityServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = DeviceCapabilityServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = DeviceCapabilityServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = DeviceCapabilityServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.DeviceCapabilityServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.DeviceCapabilityServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = DeviceCapabilityServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_rest(): + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + ] + for transport in transports: + client = DeviceCapabilityServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + ( + DeviceCapabilityServiceClient, + transports.DeviceCapabilityServiceRestTransport, + ), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_device_manufacturer_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_device_manufacturer_service.py new file mode 100644 index 000000000000..f68219a6d363 --- /dev/null +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_device_manufacturer_service.py @@ -0,0 +1,2342 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account + +from google.ads.admanager_v1.services.device_manufacturer_service import ( + DeviceManufacturerServiceClient, + pagers, + transports, +) +from google.ads.admanager_v1.types import ( + device_manufacturer_messages, + device_manufacturer_service, +) + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert DeviceManufacturerServiceClient._get_default_mtls_endpoint(None) is None + assert ( + DeviceManufacturerServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + DeviceManufacturerServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + DeviceManufacturerServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + DeviceManufacturerServiceClient._get_default_mtls_endpoint( + sandbox_mtls_endpoint + ) + == sandbox_mtls_endpoint + ) + assert ( + DeviceManufacturerServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +def test__read_environment_variables(): + assert DeviceManufacturerServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert DeviceManufacturerServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert DeviceManufacturerServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + DeviceManufacturerServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert DeviceManufacturerServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert DeviceManufacturerServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert DeviceManufacturerServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + DeviceManufacturerServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert DeviceManufacturerServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert DeviceManufacturerServiceClient._get_client_cert_source(None, False) is None + assert ( + DeviceManufacturerServiceClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + DeviceManufacturerServiceClient._get_client_cert_source( + mock_provided_cert_source, True + ) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + DeviceManufacturerServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + DeviceManufacturerServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + DeviceManufacturerServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DeviceManufacturerServiceClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = DeviceManufacturerServiceClient._DEFAULT_UNIVERSE + default_endpoint = ( + DeviceManufacturerServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + ) + mock_universe = "bar.com" + mock_endpoint = DeviceManufacturerServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + DeviceManufacturerServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + DeviceManufacturerServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == DeviceManufacturerServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + DeviceManufacturerServiceClient._get_api_endpoint( + None, None, default_universe, "auto" + ) + == default_endpoint + ) + assert ( + DeviceManufacturerServiceClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == DeviceManufacturerServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + DeviceManufacturerServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == DeviceManufacturerServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + DeviceManufacturerServiceClient._get_api_endpoint( + None, None, mock_universe, "never" + ) + == mock_endpoint + ) + assert ( + DeviceManufacturerServiceClient._get_api_endpoint( + None, None, default_universe, "never" + ) + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + DeviceManufacturerServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + DeviceManufacturerServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + DeviceManufacturerServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + DeviceManufacturerServiceClient._get_universe_domain(None, None) + == DeviceManufacturerServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + DeviceManufacturerServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DeviceManufacturerServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DeviceManufacturerServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (DeviceManufacturerServiceClient, "rest"), + ], +) +def test_device_manufacturer_service_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.DeviceManufacturerServiceRestTransport, "rest"), + ], +) +def test_device_manufacturer_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (DeviceManufacturerServiceClient, "rest"), + ], +) +def test_device_manufacturer_service_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +def test_device_manufacturer_service_client_get_transport_class(): + transport = DeviceManufacturerServiceClient.get_transport_class() + available_transports = [ + transports.DeviceManufacturerServiceRestTransport, + ] + assert transport in available_transports + + transport = DeviceManufacturerServiceClient.get_transport_class("rest") + assert transport == transports.DeviceManufacturerServiceRestTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + DeviceManufacturerServiceClient, + transports.DeviceManufacturerServiceRestTransport, + "rest", + ), + ], +) +@mock.patch.object( + DeviceManufacturerServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DeviceManufacturerServiceClient), +) +def test_device_manufacturer_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object( + DeviceManufacturerServiceClient, "get_transport_class" + ) as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object( + DeviceManufacturerServiceClient, "get_transport_class" + ) as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + DeviceManufacturerServiceClient, + transports.DeviceManufacturerServiceRestTransport, + "rest", + "true", + ), + ( + DeviceManufacturerServiceClient, + transports.DeviceManufacturerServiceRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + DeviceManufacturerServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DeviceManufacturerServiceClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_device_manufacturer_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [DeviceManufacturerServiceClient]) +@mock.patch.object( + DeviceManufacturerServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(DeviceManufacturerServiceClient), +) +def test_device_manufacturer_service_client_get_mtls_endpoint_and_cert_source( + client_class, +): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize("client_class", [DeviceManufacturerServiceClient]) +@mock.patch.object( + DeviceManufacturerServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(DeviceManufacturerServiceClient), +) +def test_device_manufacturer_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = DeviceManufacturerServiceClient._DEFAULT_UNIVERSE + default_endpoint = ( + DeviceManufacturerServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + ) + mock_universe = "bar.com" + mock_endpoint = DeviceManufacturerServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + DeviceManufacturerServiceClient, + transports.DeviceManufacturerServiceRestTransport, + "rest", + ), + ], +) +def test_device_manufacturer_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + DeviceManufacturerServiceClient, + transports.DeviceManufacturerServiceRestTransport, + "rest", + None, + ), + ], +) +def test_device_manufacturer_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_get_device_manufacturer_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_device_manufacturer + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_device_manufacturer + ] = mock_rpc + + request = {} + client.get_device_manufacturer(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_device_manufacturer(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_device_manufacturer_rest_required_fields( + request_type=device_manufacturer_service.GetDeviceManufacturerRequest, +): + transport_class = transports.DeviceManufacturerServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_device_manufacturer._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_device_manufacturer._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = device_manufacturer_messages.DeviceManufacturer() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = device_manufacturer_messages.DeviceManufacturer.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_device_manufacturer(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_device_manufacturer_rest_unset_required_fields(): + transport = transports.DeviceManufacturerServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_device_manufacturer._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_device_manufacturer_rest_flattened(): + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = device_manufacturer_messages.DeviceManufacturer() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "networks/sample1/deviceManufacturers/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = device_manufacturer_messages.DeviceManufacturer.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_device_manufacturer(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=networks/*/deviceManufacturers/*}" % client.transport._host, + args[1], + ) + + +def test_get_device_manufacturer_rest_flattened_error(transport: str = "rest"): + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_device_manufacturer( + device_manufacturer_service.GetDeviceManufacturerRequest(), + name="name_value", + ) + + +def test_list_device_manufacturers_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_device_manufacturers + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_device_manufacturers + ] = mock_rpc + + request = {} + client.list_device_manufacturers(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_device_manufacturers(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_device_manufacturers_rest_required_fields( + request_type=device_manufacturer_service.ListDeviceManufacturersRequest, +): + transport_class = transports.DeviceManufacturerServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_device_manufacturers._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_device_manufacturers._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + "skip", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = device_manufacturer_service.ListDeviceManufacturersResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = ( + device_manufacturer_service.ListDeviceManufacturersResponse.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_device_manufacturers(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_device_manufacturers_rest_unset_required_fields(): + transport = transports.DeviceManufacturerServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_device_manufacturers._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + "skip", + ) + ) + & set(("parent",)) + ) + + +def test_list_device_manufacturers_rest_flattened(): + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = device_manufacturer_service.ListDeviceManufacturersResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = device_manufacturer_service.ListDeviceManufacturersResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_device_manufacturers(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/deviceManufacturers" % client.transport._host, + args[1], + ) + + +def test_list_device_manufacturers_rest_flattened_error(transport: str = "rest"): + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_device_manufacturers( + device_manufacturer_service.ListDeviceManufacturersRequest(), + parent="parent_value", + ) + + +def test_list_device_manufacturers_rest_pager(transport: str = "rest"): + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + device_manufacturer_service.ListDeviceManufacturersResponse( + device_manufacturers=[ + device_manufacturer_messages.DeviceManufacturer(), + device_manufacturer_messages.DeviceManufacturer(), + device_manufacturer_messages.DeviceManufacturer(), + ], + next_page_token="abc", + ), + device_manufacturer_service.ListDeviceManufacturersResponse( + device_manufacturers=[], + next_page_token="def", + ), + device_manufacturer_service.ListDeviceManufacturersResponse( + device_manufacturers=[ + device_manufacturer_messages.DeviceManufacturer(), + ], + next_page_token="ghi", + ), + device_manufacturer_service.ListDeviceManufacturersResponse( + device_manufacturers=[ + device_manufacturer_messages.DeviceManufacturer(), + device_manufacturer_messages.DeviceManufacturer(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + device_manufacturer_service.ListDeviceManufacturersResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "networks/sample1"} + + pager = client.list_device_manufacturers(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, device_manufacturer_messages.DeviceManufacturer) + for i in results + ) + + pages = list(client.list_device_manufacturers(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.DeviceManufacturerServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.DeviceManufacturerServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = DeviceManufacturerServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.DeviceManufacturerServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = DeviceManufacturerServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = DeviceManufacturerServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.DeviceManufacturerServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = DeviceManufacturerServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.DeviceManufacturerServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = DeviceManufacturerServiceClient(transport=transport) + assert client.transport is transport + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.DeviceManufacturerServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_rest(): + transport = DeviceManufacturerServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_device_manufacturer_rest_bad_request( + request_type=device_manufacturer_service.GetDeviceManufacturerRequest, +): + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/deviceManufacturers/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_device_manufacturer(request) + + +@pytest.mark.parametrize( + "request_type", + [ + device_manufacturer_service.GetDeviceManufacturerRequest, + dict, + ], +) +def test_get_device_manufacturer_rest_call_success(request_type): + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/deviceManufacturers/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = device_manufacturer_messages.DeviceManufacturer( + name="name_value", + display_name="display_name_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = device_manufacturer_messages.DeviceManufacturer.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_device_manufacturer(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, device_manufacturer_messages.DeviceManufacturer) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_device_manufacturer_rest_interceptors(null_interceptor): + transport = transports.DeviceManufacturerServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DeviceManufacturerServiceRestInterceptor(), + ) + client = DeviceManufacturerServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.DeviceManufacturerServiceRestInterceptor, + "post_get_device_manufacturer", + ) as post, mock.patch.object( + transports.DeviceManufacturerServiceRestInterceptor, + "post_get_device_manufacturer_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.DeviceManufacturerServiceRestInterceptor, + "pre_get_device_manufacturer", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = device_manufacturer_service.GetDeviceManufacturerRequest.pb( + device_manufacturer_service.GetDeviceManufacturerRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = device_manufacturer_messages.DeviceManufacturer.to_json( + device_manufacturer_messages.DeviceManufacturer() + ) + req.return_value.content = return_value + + request = device_manufacturer_service.GetDeviceManufacturerRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = device_manufacturer_messages.DeviceManufacturer() + post_with_metadata.return_value = ( + device_manufacturer_messages.DeviceManufacturer(), + metadata, + ) + + client.get_device_manufacturer( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_device_manufacturers_rest_bad_request( + request_type=device_manufacturer_service.ListDeviceManufacturersRequest, +): + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_device_manufacturers(request) + + +@pytest.mark.parametrize( + "request_type", + [ + device_manufacturer_service.ListDeviceManufacturersRequest, + dict, + ], +) +def test_list_device_manufacturers_rest_call_success(request_type): + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = device_manufacturer_service.ListDeviceManufacturersResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = device_manufacturer_service.ListDeviceManufacturersResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_device_manufacturers(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListDeviceManufacturersPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_device_manufacturers_rest_interceptors(null_interceptor): + transport = transports.DeviceManufacturerServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.DeviceManufacturerServiceRestInterceptor(), + ) + client = DeviceManufacturerServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.DeviceManufacturerServiceRestInterceptor, + "post_list_device_manufacturers", + ) as post, mock.patch.object( + transports.DeviceManufacturerServiceRestInterceptor, + "post_list_device_manufacturers_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.DeviceManufacturerServiceRestInterceptor, + "pre_list_device_manufacturers", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = device_manufacturer_service.ListDeviceManufacturersRequest.pb( + device_manufacturer_service.ListDeviceManufacturersRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = ( + device_manufacturer_service.ListDeviceManufacturersResponse.to_json( + device_manufacturer_service.ListDeviceManufacturersResponse() + ) + ) + req.return_value.content = return_value + + request = device_manufacturer_service.ListDeviceManufacturersRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = ( + device_manufacturer_service.ListDeviceManufacturersResponse() + ) + post_with_metadata.return_value = ( + device_manufacturer_service.ListDeviceManufacturersResponse(), + metadata, + ) + + client.list_device_manufacturers( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "networks/sample1/operations/reports/runs/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "networks/sample1/operations/reports/runs/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_initialize_client_w_rest(): + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_device_manufacturer_empty_call_rest(): + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_device_manufacturer), "__call__" + ) as call: + client.get_device_manufacturer(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = device_manufacturer_service.GetDeviceManufacturerRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_device_manufacturers_empty_call_rest(): + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_device_manufacturers), "__call__" + ) as call: + client.list_device_manufacturers(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = device_manufacturer_service.ListDeviceManufacturersRequest() + + assert args[0] == request_msg + + +def test_device_manufacturer_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.DeviceManufacturerServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_device_manufacturer_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.ads.admanager_v1.services.device_manufacturer_service.transports.DeviceManufacturerServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.DeviceManufacturerServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "get_device_manufacturer", + "list_device_manufacturers", + "get_operation", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_device_manufacturer_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.ads.admanager_v1.services.device_manufacturer_service.transports.DeviceManufacturerServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.DeviceManufacturerServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id="octopus", + ) + + +def test_device_manufacturer_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.ads.admanager_v1.services.device_manufacturer_service.transports.DeviceManufacturerServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.DeviceManufacturerServiceTransport() + adc.assert_called_once() + + +def test_device_manufacturer_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + DeviceManufacturerServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id=None, + ) + + +def test_device_manufacturer_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.DeviceManufacturerServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_device_manufacturer_service_host_no_port(transport_name): + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_device_manufacturer_service_host_with_port(transport_name): + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_device_manufacturer_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = DeviceManufacturerServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = DeviceManufacturerServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.get_device_manufacturer._session + session2 = client2.transport.get_device_manufacturer._session + assert session1 != session2 + session1 = client1.transport.list_device_manufacturers._session + session2 = client2.transport.list_device_manufacturers._session + assert session1 != session2 + + +def test_device_manufacturer_path(): + network_code = "squid" + device_manufacturer = "clam" + expected = ( + "networks/{network_code}/deviceManufacturers/{device_manufacturer}".format( + network_code=network_code, + device_manufacturer=device_manufacturer, + ) + ) + actual = DeviceManufacturerServiceClient.device_manufacturer_path( + network_code, device_manufacturer + ) + assert expected == actual + + +def test_parse_device_manufacturer_path(): + expected = { + "network_code": "whelk", + "device_manufacturer": "octopus", + } + path = DeviceManufacturerServiceClient.device_manufacturer_path(**expected) + + # Check that the path construction is reversible. + actual = DeviceManufacturerServiceClient.parse_device_manufacturer_path(path) + assert expected == actual + + +def test_network_path(): + network_code = "oyster" + expected = "networks/{network_code}".format( + network_code=network_code, + ) + actual = DeviceManufacturerServiceClient.network_path(network_code) + assert expected == actual + + +def test_parse_network_path(): + expected = { + "network_code": "nudibranch", + } + path = DeviceManufacturerServiceClient.network_path(**expected) + + # Check that the path construction is reversible. + actual = DeviceManufacturerServiceClient.parse_network_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = DeviceManufacturerServiceClient.common_billing_account_path( + billing_account + ) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = DeviceManufacturerServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = DeviceManufacturerServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = DeviceManufacturerServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = DeviceManufacturerServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = DeviceManufacturerServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = DeviceManufacturerServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = DeviceManufacturerServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = DeviceManufacturerServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format( + project=project, + ) + actual = DeviceManufacturerServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = DeviceManufacturerServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = DeviceManufacturerServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = DeviceManufacturerServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = DeviceManufacturerServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = DeviceManufacturerServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.DeviceManufacturerServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.DeviceManufacturerServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = DeviceManufacturerServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_rest(): + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + ] + for transport in transports: + client = DeviceManufacturerServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + ( + DeviceManufacturerServiceClient, + transports.DeviceManufacturerServiceRestTransport, + ), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_mobile_carrier_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_mobile_carrier_service.py new file mode 100644 index 000000000000..25fa3573c31f --- /dev/null +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_mobile_carrier_service.py @@ -0,0 +1,2306 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account + +from google.ads.admanager_v1.services.mobile_carrier_service import ( + MobileCarrierServiceClient, + pagers, + transports, +) +from google.ads.admanager_v1.types import ( + mobile_carrier_messages, + mobile_carrier_service, +) + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert MobileCarrierServiceClient._get_default_mtls_endpoint(None) is None + assert ( + MobileCarrierServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + MobileCarrierServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + MobileCarrierServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + MobileCarrierServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + MobileCarrierServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +def test__read_environment_variables(): + assert MobileCarrierServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert MobileCarrierServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert MobileCarrierServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + MobileCarrierServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert MobileCarrierServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert MobileCarrierServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert MobileCarrierServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + MobileCarrierServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert MobileCarrierServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert MobileCarrierServiceClient._get_client_cert_source(None, False) is None + assert ( + MobileCarrierServiceClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + MobileCarrierServiceClient._get_client_cert_source( + mock_provided_cert_source, True + ) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + MobileCarrierServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + MobileCarrierServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + MobileCarrierServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(MobileCarrierServiceClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = MobileCarrierServiceClient._DEFAULT_UNIVERSE + default_endpoint = MobileCarrierServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = MobileCarrierServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + MobileCarrierServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + MobileCarrierServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == MobileCarrierServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + MobileCarrierServiceClient._get_api_endpoint( + None, None, default_universe, "auto" + ) + == default_endpoint + ) + assert ( + MobileCarrierServiceClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == MobileCarrierServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + MobileCarrierServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == MobileCarrierServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + MobileCarrierServiceClient._get_api_endpoint(None, None, mock_universe, "never") + == mock_endpoint + ) + assert ( + MobileCarrierServiceClient._get_api_endpoint( + None, None, default_universe, "never" + ) + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + MobileCarrierServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + MobileCarrierServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + MobileCarrierServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + MobileCarrierServiceClient._get_universe_domain(None, None) + == MobileCarrierServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + MobileCarrierServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = MobileCarrierServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = MobileCarrierServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (MobileCarrierServiceClient, "rest"), + ], +) +def test_mobile_carrier_service_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.MobileCarrierServiceRestTransport, "rest"), + ], +) +def test_mobile_carrier_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (MobileCarrierServiceClient, "rest"), + ], +) +def test_mobile_carrier_service_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +def test_mobile_carrier_service_client_get_transport_class(): + transport = MobileCarrierServiceClient.get_transport_class() + available_transports = [ + transports.MobileCarrierServiceRestTransport, + ] + assert transport in available_transports + + transport = MobileCarrierServiceClient.get_transport_class("rest") + assert transport == transports.MobileCarrierServiceRestTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + MobileCarrierServiceClient, + transports.MobileCarrierServiceRestTransport, + "rest", + ), + ], +) +@mock.patch.object( + MobileCarrierServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(MobileCarrierServiceClient), +) +def test_mobile_carrier_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(MobileCarrierServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(MobileCarrierServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + MobileCarrierServiceClient, + transports.MobileCarrierServiceRestTransport, + "rest", + "true", + ), + ( + MobileCarrierServiceClient, + transports.MobileCarrierServiceRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + MobileCarrierServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(MobileCarrierServiceClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_mobile_carrier_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [MobileCarrierServiceClient]) +@mock.patch.object( + MobileCarrierServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(MobileCarrierServiceClient), +) +def test_mobile_carrier_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize("client_class", [MobileCarrierServiceClient]) +@mock.patch.object( + MobileCarrierServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(MobileCarrierServiceClient), +) +def test_mobile_carrier_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = MobileCarrierServiceClient._DEFAULT_UNIVERSE + default_endpoint = MobileCarrierServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = MobileCarrierServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + MobileCarrierServiceClient, + transports.MobileCarrierServiceRestTransport, + "rest", + ), + ], +) +def test_mobile_carrier_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + MobileCarrierServiceClient, + transports.MobileCarrierServiceRestTransport, + "rest", + None, + ), + ], +) +def test_mobile_carrier_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_get_mobile_carrier_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_mobile_carrier in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_mobile_carrier + ] = mock_rpc + + request = {} + client.get_mobile_carrier(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_mobile_carrier(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_mobile_carrier_rest_required_fields( + request_type=mobile_carrier_service.GetMobileCarrierRequest, +): + transport_class = transports.MobileCarrierServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_mobile_carrier._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_mobile_carrier._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = mobile_carrier_messages.MobileCarrier() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = mobile_carrier_messages.MobileCarrier.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_mobile_carrier(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_mobile_carrier_rest_unset_required_fields(): + transport = transports.MobileCarrierServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_mobile_carrier._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_mobile_carrier_rest_flattened(): + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = mobile_carrier_messages.MobileCarrier() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "networks/sample1/mobileCarriers/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = mobile_carrier_messages.MobileCarrier.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_mobile_carrier(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=networks/*/mobileCarriers/*}" % client.transport._host, args[1] + ) + + +def test_get_mobile_carrier_rest_flattened_error(transport: str = "rest"): + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_mobile_carrier( + mobile_carrier_service.GetMobileCarrierRequest(), + name="name_value", + ) + + +def test_list_mobile_carriers_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_mobile_carriers in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_mobile_carriers + ] = mock_rpc + + request = {} + client.list_mobile_carriers(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_mobile_carriers(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_mobile_carriers_rest_required_fields( + request_type=mobile_carrier_service.ListMobileCarriersRequest, +): + transport_class = transports.MobileCarrierServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_mobile_carriers._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_mobile_carriers._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + "skip", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = mobile_carrier_service.ListMobileCarriersResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = mobile_carrier_service.ListMobileCarriersResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_mobile_carriers(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_mobile_carriers_rest_unset_required_fields(): + transport = transports.MobileCarrierServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_mobile_carriers._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + "skip", + ) + ) + & set(("parent",)) + ) + + +def test_list_mobile_carriers_rest_flattened(): + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = mobile_carrier_service.ListMobileCarriersResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = mobile_carrier_service.ListMobileCarriersResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_mobile_carriers(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/mobileCarriers" % client.transport._host, args[1] + ) + + +def test_list_mobile_carriers_rest_flattened_error(transport: str = "rest"): + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_mobile_carriers( + mobile_carrier_service.ListMobileCarriersRequest(), + parent="parent_value", + ) + + +def test_list_mobile_carriers_rest_pager(transport: str = "rest"): + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + mobile_carrier_service.ListMobileCarriersResponse( + mobile_carriers=[ + mobile_carrier_messages.MobileCarrier(), + mobile_carrier_messages.MobileCarrier(), + mobile_carrier_messages.MobileCarrier(), + ], + next_page_token="abc", + ), + mobile_carrier_service.ListMobileCarriersResponse( + mobile_carriers=[], + next_page_token="def", + ), + mobile_carrier_service.ListMobileCarriersResponse( + mobile_carriers=[ + mobile_carrier_messages.MobileCarrier(), + ], + next_page_token="ghi", + ), + mobile_carrier_service.ListMobileCarriersResponse( + mobile_carriers=[ + mobile_carrier_messages.MobileCarrier(), + mobile_carrier_messages.MobileCarrier(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + mobile_carrier_service.ListMobileCarriersResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "networks/sample1"} + + pager = client.list_mobile_carriers(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, mobile_carrier_messages.MobileCarrier) for i in results + ) + + pages = list(client.list_mobile_carriers(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.MobileCarrierServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.MobileCarrierServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = MobileCarrierServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.MobileCarrierServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = MobileCarrierServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = MobileCarrierServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.MobileCarrierServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = MobileCarrierServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.MobileCarrierServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = MobileCarrierServiceClient(transport=transport) + assert client.transport is transport + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.MobileCarrierServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_rest(): + transport = MobileCarrierServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_mobile_carrier_rest_bad_request( + request_type=mobile_carrier_service.GetMobileCarrierRequest, +): + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/mobileCarriers/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_mobile_carrier(request) + + +@pytest.mark.parametrize( + "request_type", + [ + mobile_carrier_service.GetMobileCarrierRequest, + dict, + ], +) +def test_get_mobile_carrier_rest_call_success(request_type): + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/mobileCarriers/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = mobile_carrier_messages.MobileCarrier( + name="name_value", + display_name="display_name_value", + region_code="region_code_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = mobile_carrier_messages.MobileCarrier.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_mobile_carrier(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, mobile_carrier_messages.MobileCarrier) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.region_code == "region_code_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_mobile_carrier_rest_interceptors(null_interceptor): + transport = transports.MobileCarrierServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.MobileCarrierServiceRestInterceptor(), + ) + client = MobileCarrierServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.MobileCarrierServiceRestInterceptor, "post_get_mobile_carrier" + ) as post, mock.patch.object( + transports.MobileCarrierServiceRestInterceptor, + "post_get_mobile_carrier_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.MobileCarrierServiceRestInterceptor, "pre_get_mobile_carrier" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = mobile_carrier_service.GetMobileCarrierRequest.pb( + mobile_carrier_service.GetMobileCarrierRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = mobile_carrier_messages.MobileCarrier.to_json( + mobile_carrier_messages.MobileCarrier() + ) + req.return_value.content = return_value + + request = mobile_carrier_service.GetMobileCarrierRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = mobile_carrier_messages.MobileCarrier() + post_with_metadata.return_value = ( + mobile_carrier_messages.MobileCarrier(), + metadata, + ) + + client.get_mobile_carrier( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_mobile_carriers_rest_bad_request( + request_type=mobile_carrier_service.ListMobileCarriersRequest, +): + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_mobile_carriers(request) + + +@pytest.mark.parametrize( + "request_type", + [ + mobile_carrier_service.ListMobileCarriersRequest, + dict, + ], +) +def test_list_mobile_carriers_rest_call_success(request_type): + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = mobile_carrier_service.ListMobileCarriersResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = mobile_carrier_service.ListMobileCarriersResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_mobile_carriers(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListMobileCarriersPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_mobile_carriers_rest_interceptors(null_interceptor): + transport = transports.MobileCarrierServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.MobileCarrierServiceRestInterceptor(), + ) + client = MobileCarrierServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.MobileCarrierServiceRestInterceptor, "post_list_mobile_carriers" + ) as post, mock.patch.object( + transports.MobileCarrierServiceRestInterceptor, + "post_list_mobile_carriers_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.MobileCarrierServiceRestInterceptor, "pre_list_mobile_carriers" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = mobile_carrier_service.ListMobileCarriersRequest.pb( + mobile_carrier_service.ListMobileCarriersRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = mobile_carrier_service.ListMobileCarriersResponse.to_json( + mobile_carrier_service.ListMobileCarriersResponse() + ) + req.return_value.content = return_value + + request = mobile_carrier_service.ListMobileCarriersRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = mobile_carrier_service.ListMobileCarriersResponse() + post_with_metadata.return_value = ( + mobile_carrier_service.ListMobileCarriersResponse(), + metadata, + ) + + client.list_mobile_carriers( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "networks/sample1/operations/reports/runs/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "networks/sample1/operations/reports/runs/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_initialize_client_w_rest(): + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_mobile_carrier_empty_call_rest(): + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_mobile_carrier), "__call__" + ) as call: + client.get_mobile_carrier(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = mobile_carrier_service.GetMobileCarrierRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_mobile_carriers_empty_call_rest(): + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_mobile_carriers), "__call__" + ) as call: + client.list_mobile_carriers(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = mobile_carrier_service.ListMobileCarriersRequest() + + assert args[0] == request_msg + + +def test_mobile_carrier_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.MobileCarrierServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_mobile_carrier_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.ads.admanager_v1.services.mobile_carrier_service.transports.MobileCarrierServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.MobileCarrierServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "get_mobile_carrier", + "list_mobile_carriers", + "get_operation", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_mobile_carrier_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.ads.admanager_v1.services.mobile_carrier_service.transports.MobileCarrierServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.MobileCarrierServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id="octopus", + ) + + +def test_mobile_carrier_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.ads.admanager_v1.services.mobile_carrier_service.transports.MobileCarrierServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.MobileCarrierServiceTransport() + adc.assert_called_once() + + +def test_mobile_carrier_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + MobileCarrierServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id=None, + ) + + +def test_mobile_carrier_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.MobileCarrierServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_mobile_carrier_service_host_no_port(transport_name): + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_mobile_carrier_service_host_with_port(transport_name): + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_mobile_carrier_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = MobileCarrierServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = MobileCarrierServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.get_mobile_carrier._session + session2 = client2.transport.get_mobile_carrier._session + assert session1 != session2 + session1 = client1.transport.list_mobile_carriers._session + session2 = client2.transport.list_mobile_carriers._session + assert session1 != session2 + + +def test_mobile_carrier_path(): + network_code = "squid" + mobile_carrier = "clam" + expected = "networks/{network_code}/mobileCarriers/{mobile_carrier}".format( + network_code=network_code, + mobile_carrier=mobile_carrier, + ) + actual = MobileCarrierServiceClient.mobile_carrier_path( + network_code, mobile_carrier + ) + assert expected == actual + + +def test_parse_mobile_carrier_path(): + expected = { + "network_code": "whelk", + "mobile_carrier": "octopus", + } + path = MobileCarrierServiceClient.mobile_carrier_path(**expected) + + # Check that the path construction is reversible. + actual = MobileCarrierServiceClient.parse_mobile_carrier_path(path) + assert expected == actual + + +def test_network_path(): + network_code = "oyster" + expected = "networks/{network_code}".format( + network_code=network_code, + ) + actual = MobileCarrierServiceClient.network_path(network_code) + assert expected == actual + + +def test_parse_network_path(): + expected = { + "network_code": "nudibranch", + } + path = MobileCarrierServiceClient.network_path(**expected) + + # Check that the path construction is reversible. + actual = MobileCarrierServiceClient.parse_network_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = MobileCarrierServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = MobileCarrierServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = MobileCarrierServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = MobileCarrierServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = MobileCarrierServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = MobileCarrierServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = MobileCarrierServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = MobileCarrierServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = MobileCarrierServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format( + project=project, + ) + actual = MobileCarrierServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = MobileCarrierServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = MobileCarrierServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = MobileCarrierServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = MobileCarrierServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = MobileCarrierServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.MobileCarrierServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.MobileCarrierServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = MobileCarrierServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_rest(): + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + ] + for transport in transports: + client = MobileCarrierServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (MobileCarrierServiceClient, transports.MobileCarrierServiceRestTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_mobile_device_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_mobile_device_service.py new file mode 100644 index 000000000000..708346e03088 --- /dev/null +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_mobile_device_service.py @@ -0,0 +1,2319 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account + +from google.ads.admanager_v1.services.mobile_device_service import ( + MobileDeviceServiceClient, + pagers, + transports, +) +from google.ads.admanager_v1.types import mobile_device_messages, mobile_device_service + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert MobileDeviceServiceClient._get_default_mtls_endpoint(None) is None + assert ( + MobileDeviceServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + MobileDeviceServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + MobileDeviceServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + MobileDeviceServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + MobileDeviceServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +def test__read_environment_variables(): + assert MobileDeviceServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert MobileDeviceServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert MobileDeviceServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + MobileDeviceServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert MobileDeviceServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert MobileDeviceServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert MobileDeviceServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + MobileDeviceServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert MobileDeviceServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert MobileDeviceServiceClient._get_client_cert_source(None, False) is None + assert ( + MobileDeviceServiceClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + MobileDeviceServiceClient._get_client_cert_source( + mock_provided_cert_source, True + ) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + MobileDeviceServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + MobileDeviceServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + MobileDeviceServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(MobileDeviceServiceClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = MobileDeviceServiceClient._DEFAULT_UNIVERSE + default_endpoint = MobileDeviceServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = MobileDeviceServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + MobileDeviceServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + MobileDeviceServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == MobileDeviceServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + MobileDeviceServiceClient._get_api_endpoint( + None, None, default_universe, "auto" + ) + == default_endpoint + ) + assert ( + MobileDeviceServiceClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == MobileDeviceServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + MobileDeviceServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == MobileDeviceServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + MobileDeviceServiceClient._get_api_endpoint(None, None, mock_universe, "never") + == mock_endpoint + ) + assert ( + MobileDeviceServiceClient._get_api_endpoint( + None, None, default_universe, "never" + ) + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + MobileDeviceServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + MobileDeviceServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + MobileDeviceServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + MobileDeviceServiceClient._get_universe_domain(None, None) + == MobileDeviceServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + MobileDeviceServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = MobileDeviceServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = MobileDeviceServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (MobileDeviceServiceClient, "rest"), + ], +) +def test_mobile_device_service_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.MobileDeviceServiceRestTransport, "rest"), + ], +) +def test_mobile_device_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (MobileDeviceServiceClient, "rest"), + ], +) +def test_mobile_device_service_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +def test_mobile_device_service_client_get_transport_class(): + transport = MobileDeviceServiceClient.get_transport_class() + available_transports = [ + transports.MobileDeviceServiceRestTransport, + ] + assert transport in available_transports + + transport = MobileDeviceServiceClient.get_transport_class("rest") + assert transport == transports.MobileDeviceServiceRestTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + MobileDeviceServiceClient, + transports.MobileDeviceServiceRestTransport, + "rest", + ), + ], +) +@mock.patch.object( + MobileDeviceServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(MobileDeviceServiceClient), +) +def test_mobile_device_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(MobileDeviceServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(MobileDeviceServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + MobileDeviceServiceClient, + transports.MobileDeviceServiceRestTransport, + "rest", + "true", + ), + ( + MobileDeviceServiceClient, + transports.MobileDeviceServiceRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + MobileDeviceServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(MobileDeviceServiceClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_mobile_device_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [MobileDeviceServiceClient]) +@mock.patch.object( + MobileDeviceServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(MobileDeviceServiceClient), +) +def test_mobile_device_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize("client_class", [MobileDeviceServiceClient]) +@mock.patch.object( + MobileDeviceServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(MobileDeviceServiceClient), +) +def test_mobile_device_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = MobileDeviceServiceClient._DEFAULT_UNIVERSE + default_endpoint = MobileDeviceServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = MobileDeviceServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + MobileDeviceServiceClient, + transports.MobileDeviceServiceRestTransport, + "rest", + ), + ], +) +def test_mobile_device_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + MobileDeviceServiceClient, + transports.MobileDeviceServiceRestTransport, + "rest", + None, + ), + ], +) +def test_mobile_device_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_get_mobile_device_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_mobile_device in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_mobile_device + ] = mock_rpc + + request = {} + client.get_mobile_device(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_mobile_device(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_mobile_device_rest_required_fields( + request_type=mobile_device_service.GetMobileDeviceRequest, +): + transport_class = transports.MobileDeviceServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_mobile_device._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_mobile_device._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = mobile_device_messages.MobileDevice() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = mobile_device_messages.MobileDevice.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_mobile_device(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_mobile_device_rest_unset_required_fields(): + transport = transports.MobileDeviceServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_mobile_device._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_mobile_device_rest_flattened(): + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = mobile_device_messages.MobileDevice() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "networks/sample1/mobileDevices/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = mobile_device_messages.MobileDevice.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_mobile_device(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=networks/*/mobileDevices/*}" % client.transport._host, args[1] + ) + + +def test_get_mobile_device_rest_flattened_error(transport: str = "rest"): + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_mobile_device( + mobile_device_service.GetMobileDeviceRequest(), + name="name_value", + ) + + +def test_list_mobile_devices_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_mobile_devices in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_mobile_devices + ] = mock_rpc + + request = {} + client.list_mobile_devices(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_mobile_devices(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_mobile_devices_rest_required_fields( + request_type=mobile_device_service.ListMobileDevicesRequest, +): + transport_class = transports.MobileDeviceServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_mobile_devices._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_mobile_devices._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + "skip", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = mobile_device_service.ListMobileDevicesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = mobile_device_service.ListMobileDevicesResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_mobile_devices(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_mobile_devices_rest_unset_required_fields(): + transport = transports.MobileDeviceServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_mobile_devices._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + "skip", + ) + ) + & set(("parent",)) + ) + + +def test_list_mobile_devices_rest_flattened(): + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = mobile_device_service.ListMobileDevicesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = mobile_device_service.ListMobileDevicesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_mobile_devices(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/mobileDevices" % client.transport._host, args[1] + ) + + +def test_list_mobile_devices_rest_flattened_error(transport: str = "rest"): + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_mobile_devices( + mobile_device_service.ListMobileDevicesRequest(), + parent="parent_value", + ) + + +def test_list_mobile_devices_rest_pager(transport: str = "rest"): + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + mobile_device_service.ListMobileDevicesResponse( + mobile_devices=[ + mobile_device_messages.MobileDevice(), + mobile_device_messages.MobileDevice(), + mobile_device_messages.MobileDevice(), + ], + next_page_token="abc", + ), + mobile_device_service.ListMobileDevicesResponse( + mobile_devices=[], + next_page_token="def", + ), + mobile_device_service.ListMobileDevicesResponse( + mobile_devices=[ + mobile_device_messages.MobileDevice(), + ], + next_page_token="ghi", + ), + mobile_device_service.ListMobileDevicesResponse( + mobile_devices=[ + mobile_device_messages.MobileDevice(), + mobile_device_messages.MobileDevice(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + mobile_device_service.ListMobileDevicesResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "networks/sample1"} + + pager = client.list_mobile_devices(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, mobile_device_messages.MobileDevice) for i in results) + + pages = list(client.list_mobile_devices(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.MobileDeviceServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.MobileDeviceServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = MobileDeviceServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.MobileDeviceServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = MobileDeviceServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = MobileDeviceServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.MobileDeviceServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = MobileDeviceServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.MobileDeviceServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = MobileDeviceServiceClient(transport=transport) + assert client.transport is transport + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.MobileDeviceServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_rest(): + transport = MobileDeviceServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_mobile_device_rest_bad_request( + request_type=mobile_device_service.GetMobileDeviceRequest, +): + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/mobileDevices/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_mobile_device(request) + + +@pytest.mark.parametrize( + "request_type", + [ + mobile_device_service.GetMobileDeviceRequest, + dict, + ], +) +def test_get_mobile_device_rest_call_success(request_type): + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/mobileDevices/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = mobile_device_messages.MobileDevice( + name="name_value", + display_name="display_name_value", + manufacturer="manufacturer_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = mobile_device_messages.MobileDevice.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_mobile_device(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, mobile_device_messages.MobileDevice) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.manufacturer == "manufacturer_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_mobile_device_rest_interceptors(null_interceptor): + transport = transports.MobileDeviceServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.MobileDeviceServiceRestInterceptor(), + ) + client = MobileDeviceServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.MobileDeviceServiceRestInterceptor, "post_get_mobile_device" + ) as post, mock.patch.object( + transports.MobileDeviceServiceRestInterceptor, + "post_get_mobile_device_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.MobileDeviceServiceRestInterceptor, "pre_get_mobile_device" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = mobile_device_service.GetMobileDeviceRequest.pb( + mobile_device_service.GetMobileDeviceRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = mobile_device_messages.MobileDevice.to_json( + mobile_device_messages.MobileDevice() + ) + req.return_value.content = return_value + + request = mobile_device_service.GetMobileDeviceRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = mobile_device_messages.MobileDevice() + post_with_metadata.return_value = ( + mobile_device_messages.MobileDevice(), + metadata, + ) + + client.get_mobile_device( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_mobile_devices_rest_bad_request( + request_type=mobile_device_service.ListMobileDevicesRequest, +): + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_mobile_devices(request) + + +@pytest.mark.parametrize( + "request_type", + [ + mobile_device_service.ListMobileDevicesRequest, + dict, + ], +) +def test_list_mobile_devices_rest_call_success(request_type): + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = mobile_device_service.ListMobileDevicesResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = mobile_device_service.ListMobileDevicesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_mobile_devices(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListMobileDevicesPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_mobile_devices_rest_interceptors(null_interceptor): + transport = transports.MobileDeviceServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.MobileDeviceServiceRestInterceptor(), + ) + client = MobileDeviceServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.MobileDeviceServiceRestInterceptor, "post_list_mobile_devices" + ) as post, mock.patch.object( + transports.MobileDeviceServiceRestInterceptor, + "post_list_mobile_devices_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.MobileDeviceServiceRestInterceptor, "pre_list_mobile_devices" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = mobile_device_service.ListMobileDevicesRequest.pb( + mobile_device_service.ListMobileDevicesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = mobile_device_service.ListMobileDevicesResponse.to_json( + mobile_device_service.ListMobileDevicesResponse() + ) + req.return_value.content = return_value + + request = mobile_device_service.ListMobileDevicesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = mobile_device_service.ListMobileDevicesResponse() + post_with_metadata.return_value = ( + mobile_device_service.ListMobileDevicesResponse(), + metadata, + ) + + client.list_mobile_devices( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "networks/sample1/operations/reports/runs/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "networks/sample1/operations/reports/runs/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_initialize_client_w_rest(): + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_mobile_device_empty_call_rest(): + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_mobile_device), "__call__" + ) as call: + client.get_mobile_device(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = mobile_device_service.GetMobileDeviceRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_mobile_devices_empty_call_rest(): + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_mobile_devices), "__call__" + ) as call: + client.list_mobile_devices(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = mobile_device_service.ListMobileDevicesRequest() + + assert args[0] == request_msg + + +def test_mobile_device_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.MobileDeviceServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_mobile_device_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.ads.admanager_v1.services.mobile_device_service.transports.MobileDeviceServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.MobileDeviceServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "get_mobile_device", + "list_mobile_devices", + "get_operation", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_mobile_device_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.ads.admanager_v1.services.mobile_device_service.transports.MobileDeviceServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.MobileDeviceServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id="octopus", + ) + + +def test_mobile_device_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.ads.admanager_v1.services.mobile_device_service.transports.MobileDeviceServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.MobileDeviceServiceTransport() + adc.assert_called_once() + + +def test_mobile_device_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + MobileDeviceServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id=None, + ) + + +def test_mobile_device_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.MobileDeviceServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_mobile_device_service_host_no_port(transport_name): + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_mobile_device_service_host_with_port(transport_name): + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_mobile_device_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = MobileDeviceServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = MobileDeviceServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.get_mobile_device._session + session2 = client2.transport.get_mobile_device._session + assert session1 != session2 + session1 = client1.transport.list_mobile_devices._session + session2 = client2.transport.list_mobile_devices._session + assert session1 != session2 + + +def test_device_manufacturer_path(): + network_code = "squid" + device_manufacturer = "clam" + expected = ( + "networks/{network_code}/deviceManufacturers/{device_manufacturer}".format( + network_code=network_code, + device_manufacturer=device_manufacturer, + ) + ) + actual = MobileDeviceServiceClient.device_manufacturer_path( + network_code, device_manufacturer + ) + assert expected == actual + + +def test_parse_device_manufacturer_path(): + expected = { + "network_code": "whelk", + "device_manufacturer": "octopus", + } + path = MobileDeviceServiceClient.device_manufacturer_path(**expected) + + # Check that the path construction is reversible. + actual = MobileDeviceServiceClient.parse_device_manufacturer_path(path) + assert expected == actual + + +def test_mobile_device_path(): + network_code = "oyster" + mobile_device = "nudibranch" + expected = "networks/{network_code}/mobileDevices/{mobile_device}".format( + network_code=network_code, + mobile_device=mobile_device, + ) + actual = MobileDeviceServiceClient.mobile_device_path(network_code, mobile_device) + assert expected == actual + + +def test_parse_mobile_device_path(): + expected = { + "network_code": "cuttlefish", + "mobile_device": "mussel", + } + path = MobileDeviceServiceClient.mobile_device_path(**expected) + + # Check that the path construction is reversible. + actual = MobileDeviceServiceClient.parse_mobile_device_path(path) + assert expected == actual + + +def test_network_path(): + network_code = "winkle" + expected = "networks/{network_code}".format( + network_code=network_code, + ) + actual = MobileDeviceServiceClient.network_path(network_code) + assert expected == actual + + +def test_parse_network_path(): + expected = { + "network_code": "nautilus", + } + path = MobileDeviceServiceClient.network_path(**expected) + + # Check that the path construction is reversible. + actual = MobileDeviceServiceClient.parse_network_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "scallop" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = MobileDeviceServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "abalone", + } + path = MobileDeviceServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = MobileDeviceServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "squid" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = MobileDeviceServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "clam", + } + path = MobileDeviceServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = MobileDeviceServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "whelk" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = MobileDeviceServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "octopus", + } + path = MobileDeviceServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = MobileDeviceServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "oyster" + expected = "projects/{project}".format( + project=project, + ) + actual = MobileDeviceServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nudibranch", + } + path = MobileDeviceServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = MobileDeviceServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "cuttlefish" + location = "mussel" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = MobileDeviceServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "winkle", + "location": "nautilus", + } + path = MobileDeviceServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = MobileDeviceServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.MobileDeviceServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.MobileDeviceServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = MobileDeviceServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_rest(): + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + ] + for transport in transports: + client = MobileDeviceServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (MobileDeviceServiceClient, transports.MobileDeviceServiceRestTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_mobile_device_submodel_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_mobile_device_submodel_service.py new file mode 100644 index 000000000000..df2ea8642597 --- /dev/null +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_mobile_device_submodel_service.py @@ -0,0 +1,2385 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account + +from google.ads.admanager_v1.services.mobile_device_submodel_service import ( + MobileDeviceSubmodelServiceClient, + pagers, + transports, +) +from google.ads.admanager_v1.types import ( + mobile_device_submodel_messages, + mobile_device_submodel_service, +) + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert MobileDeviceSubmodelServiceClient._get_default_mtls_endpoint(None) is None + assert ( + MobileDeviceSubmodelServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + MobileDeviceSubmodelServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + MobileDeviceSubmodelServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + MobileDeviceSubmodelServiceClient._get_default_mtls_endpoint( + sandbox_mtls_endpoint + ) + == sandbox_mtls_endpoint + ) + assert ( + MobileDeviceSubmodelServiceClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +def test__read_environment_variables(): + assert MobileDeviceSubmodelServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert MobileDeviceSubmodelServiceClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert MobileDeviceSubmodelServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + MobileDeviceSubmodelServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert MobileDeviceSubmodelServiceClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert MobileDeviceSubmodelServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert MobileDeviceSubmodelServiceClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + MobileDeviceSubmodelServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert MobileDeviceSubmodelServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert ( + MobileDeviceSubmodelServiceClient._get_client_cert_source(None, False) is None + ) + assert ( + MobileDeviceSubmodelServiceClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + MobileDeviceSubmodelServiceClient._get_client_cert_source( + mock_provided_cert_source, True + ) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + MobileDeviceSubmodelServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + MobileDeviceSubmodelServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + MobileDeviceSubmodelServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(MobileDeviceSubmodelServiceClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = MobileDeviceSubmodelServiceClient._DEFAULT_UNIVERSE + default_endpoint = ( + MobileDeviceSubmodelServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + ) + mock_universe = "bar.com" + mock_endpoint = MobileDeviceSubmodelServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + MobileDeviceSubmodelServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + MobileDeviceSubmodelServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == MobileDeviceSubmodelServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + MobileDeviceSubmodelServiceClient._get_api_endpoint( + None, None, default_universe, "auto" + ) + == default_endpoint + ) + assert ( + MobileDeviceSubmodelServiceClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == MobileDeviceSubmodelServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + MobileDeviceSubmodelServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == MobileDeviceSubmodelServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + MobileDeviceSubmodelServiceClient._get_api_endpoint( + None, None, mock_universe, "never" + ) + == mock_endpoint + ) + assert ( + MobileDeviceSubmodelServiceClient._get_api_endpoint( + None, None, default_universe, "never" + ) + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + MobileDeviceSubmodelServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + MobileDeviceSubmodelServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + MobileDeviceSubmodelServiceClient._get_universe_domain( + None, universe_domain_env + ) + == universe_domain_env + ) + assert ( + MobileDeviceSubmodelServiceClient._get_universe_domain(None, None) + == MobileDeviceSubmodelServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + MobileDeviceSubmodelServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = MobileDeviceSubmodelServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = MobileDeviceSubmodelServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (MobileDeviceSubmodelServiceClient, "rest"), + ], +) +def test_mobile_device_submodel_service_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.MobileDeviceSubmodelServiceRestTransport, "rest"), + ], +) +def test_mobile_device_submodel_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (MobileDeviceSubmodelServiceClient, "rest"), + ], +) +def test_mobile_device_submodel_service_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +def test_mobile_device_submodel_service_client_get_transport_class(): + transport = MobileDeviceSubmodelServiceClient.get_transport_class() + available_transports = [ + transports.MobileDeviceSubmodelServiceRestTransport, + ] + assert transport in available_transports + + transport = MobileDeviceSubmodelServiceClient.get_transport_class("rest") + assert transport == transports.MobileDeviceSubmodelServiceRestTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + MobileDeviceSubmodelServiceClient, + transports.MobileDeviceSubmodelServiceRestTransport, + "rest", + ), + ], +) +@mock.patch.object( + MobileDeviceSubmodelServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(MobileDeviceSubmodelServiceClient), +) +def test_mobile_device_submodel_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object( + MobileDeviceSubmodelServiceClient, "get_transport_class" + ) as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object( + MobileDeviceSubmodelServiceClient, "get_transport_class" + ) as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + MobileDeviceSubmodelServiceClient, + transports.MobileDeviceSubmodelServiceRestTransport, + "rest", + "true", + ), + ( + MobileDeviceSubmodelServiceClient, + transports.MobileDeviceSubmodelServiceRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + MobileDeviceSubmodelServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(MobileDeviceSubmodelServiceClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_mobile_device_submodel_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [MobileDeviceSubmodelServiceClient]) +@mock.patch.object( + MobileDeviceSubmodelServiceClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(MobileDeviceSubmodelServiceClient), +) +def test_mobile_device_submodel_service_client_get_mtls_endpoint_and_cert_source( + client_class, +): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize("client_class", [MobileDeviceSubmodelServiceClient]) +@mock.patch.object( + MobileDeviceSubmodelServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(MobileDeviceSubmodelServiceClient), +) +def test_mobile_device_submodel_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = MobileDeviceSubmodelServiceClient._DEFAULT_UNIVERSE + default_endpoint = ( + MobileDeviceSubmodelServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + ) + mock_universe = "bar.com" + mock_endpoint = MobileDeviceSubmodelServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + MobileDeviceSubmodelServiceClient, + transports.MobileDeviceSubmodelServiceRestTransport, + "rest", + ), + ], +) +def test_mobile_device_submodel_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + MobileDeviceSubmodelServiceClient, + transports.MobileDeviceSubmodelServiceRestTransport, + "rest", + None, + ), + ], +) +def test_mobile_device_submodel_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_get_mobile_device_submodel_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_mobile_device_submodel + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_mobile_device_submodel + ] = mock_rpc + + request = {} + client.get_mobile_device_submodel(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_mobile_device_submodel(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_mobile_device_submodel_rest_required_fields( + request_type=mobile_device_submodel_service.GetMobileDeviceSubmodelRequest, +): + transport_class = transports.MobileDeviceSubmodelServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_mobile_device_submodel._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_mobile_device_submodel._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = mobile_device_submodel_messages.MobileDeviceSubmodel() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = mobile_device_submodel_messages.MobileDeviceSubmodel.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_mobile_device_submodel(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_mobile_device_submodel_rest_unset_required_fields(): + transport = transports.MobileDeviceSubmodelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_mobile_device_submodel._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_mobile_device_submodel_rest_flattened(): + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = mobile_device_submodel_messages.MobileDeviceSubmodel() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "networks/sample1/mobileDeviceSubmodels/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = mobile_device_submodel_messages.MobileDeviceSubmodel.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_mobile_device_submodel(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=networks/*/mobileDeviceSubmodels/*}" % client.transport._host, + args[1], + ) + + +def test_get_mobile_device_submodel_rest_flattened_error(transport: str = "rest"): + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_mobile_device_submodel( + mobile_device_submodel_service.GetMobileDeviceSubmodelRequest(), + name="name_value", + ) + + +def test_list_mobile_device_submodels_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_mobile_device_submodels + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_mobile_device_submodels + ] = mock_rpc + + request = {} + client.list_mobile_device_submodels(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_mobile_device_submodels(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_mobile_device_submodels_rest_required_fields( + request_type=mobile_device_submodel_service.ListMobileDeviceSubmodelsRequest, +): + transport_class = transports.MobileDeviceSubmodelServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_mobile_device_submodels._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_mobile_device_submodels._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + "skip", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = ( + mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_mobile_device_submodels(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_mobile_device_submodels_rest_unset_required_fields(): + transport = transports.MobileDeviceSubmodelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_mobile_device_submodels._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + "skip", + ) + ) + & set(("parent",)) + ) + + +def test_list_mobile_device_submodels_rest_flattened(): + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = ( + mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse() + ) + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = ( + mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_mobile_device_submodels(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/mobileDeviceSubmodels" % client.transport._host, + args[1], + ) + + +def test_list_mobile_device_submodels_rest_flattened_error(transport: str = "rest"): + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_mobile_device_submodels( + mobile_device_submodel_service.ListMobileDeviceSubmodelsRequest(), + parent="parent_value", + ) + + +def test_list_mobile_device_submodels_rest_pager(transport: str = "rest"): + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse( + mobile_device_submodels=[ + mobile_device_submodel_messages.MobileDeviceSubmodel(), + mobile_device_submodel_messages.MobileDeviceSubmodel(), + mobile_device_submodel_messages.MobileDeviceSubmodel(), + ], + next_page_token="abc", + ), + mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse( + mobile_device_submodels=[], + next_page_token="def", + ), + mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse( + mobile_device_submodels=[ + mobile_device_submodel_messages.MobileDeviceSubmodel(), + ], + next_page_token="ghi", + ), + mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse( + mobile_device_submodels=[ + mobile_device_submodel_messages.MobileDeviceSubmodel(), + mobile_device_submodel_messages.MobileDeviceSubmodel(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "networks/sample1"} + + pager = client.list_mobile_device_submodels(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, mobile_device_submodel_messages.MobileDeviceSubmodel) + for i in results + ) + + pages = list(client.list_mobile_device_submodels(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.MobileDeviceSubmodelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.MobileDeviceSubmodelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = MobileDeviceSubmodelServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.MobileDeviceSubmodelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = MobileDeviceSubmodelServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = MobileDeviceSubmodelServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.MobileDeviceSubmodelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = MobileDeviceSubmodelServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.MobileDeviceSubmodelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = MobileDeviceSubmodelServiceClient(transport=transport) + assert client.transport is transport + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.MobileDeviceSubmodelServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_rest(): + transport = MobileDeviceSubmodelServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_mobile_device_submodel_rest_bad_request( + request_type=mobile_device_submodel_service.GetMobileDeviceSubmodelRequest, +): + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/mobileDeviceSubmodels/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_mobile_device_submodel(request) + + +@pytest.mark.parametrize( + "request_type", + [ + mobile_device_submodel_service.GetMobileDeviceSubmodelRequest, + dict, + ], +) +def test_get_mobile_device_submodel_rest_call_success(request_type): + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/mobileDeviceSubmodels/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = mobile_device_submodel_messages.MobileDeviceSubmodel( + name="name_value", + display_name="display_name_value", + mobile_device="mobile_device_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = mobile_device_submodel_messages.MobileDeviceSubmodel.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_mobile_device_submodel(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, mobile_device_submodel_messages.MobileDeviceSubmodel) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.mobile_device == "mobile_device_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_mobile_device_submodel_rest_interceptors(null_interceptor): + transport = transports.MobileDeviceSubmodelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.MobileDeviceSubmodelServiceRestInterceptor(), + ) + client = MobileDeviceSubmodelServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.MobileDeviceSubmodelServiceRestInterceptor, + "post_get_mobile_device_submodel", + ) as post, mock.patch.object( + transports.MobileDeviceSubmodelServiceRestInterceptor, + "post_get_mobile_device_submodel_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.MobileDeviceSubmodelServiceRestInterceptor, + "pre_get_mobile_device_submodel", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = mobile_device_submodel_service.GetMobileDeviceSubmodelRequest.pb( + mobile_device_submodel_service.GetMobileDeviceSubmodelRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = mobile_device_submodel_messages.MobileDeviceSubmodel.to_json( + mobile_device_submodel_messages.MobileDeviceSubmodel() + ) + req.return_value.content = return_value + + request = mobile_device_submodel_service.GetMobileDeviceSubmodelRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = mobile_device_submodel_messages.MobileDeviceSubmodel() + post_with_metadata.return_value = ( + mobile_device_submodel_messages.MobileDeviceSubmodel(), + metadata, + ) + + client.get_mobile_device_submodel( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_mobile_device_submodels_rest_bad_request( + request_type=mobile_device_submodel_service.ListMobileDeviceSubmodelsRequest, +): + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_mobile_device_submodels(request) + + +@pytest.mark.parametrize( + "request_type", + [ + mobile_device_submodel_service.ListMobileDeviceSubmodelsRequest, + dict, + ], +) +def test_list_mobile_device_submodels_rest_call_success(request_type): + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = ( + mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse.pb( + return_value + ) + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_mobile_device_submodels(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListMobileDeviceSubmodelsPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_mobile_device_submodels_rest_interceptors(null_interceptor): + transport = transports.MobileDeviceSubmodelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.MobileDeviceSubmodelServiceRestInterceptor(), + ) + client = MobileDeviceSubmodelServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.MobileDeviceSubmodelServiceRestInterceptor, + "post_list_mobile_device_submodels", + ) as post, mock.patch.object( + transports.MobileDeviceSubmodelServiceRestInterceptor, + "post_list_mobile_device_submodels_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.MobileDeviceSubmodelServiceRestInterceptor, + "pre_list_mobile_device_submodels", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = mobile_device_submodel_service.ListMobileDeviceSubmodelsRequest.pb( + mobile_device_submodel_service.ListMobileDeviceSubmodelsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = ( + mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse.to_json( + mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse() + ) + ) + req.return_value.content = return_value + + request = mobile_device_submodel_service.ListMobileDeviceSubmodelsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = ( + mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse() + ) + post_with_metadata.return_value = ( + mobile_device_submodel_service.ListMobileDeviceSubmodelsResponse(), + metadata, + ) + + client.list_mobile_device_submodels( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "networks/sample1/operations/reports/runs/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "networks/sample1/operations/reports/runs/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_initialize_client_w_rest(): + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_mobile_device_submodel_empty_call_rest(): + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_mobile_device_submodel), "__call__" + ) as call: + client.get_mobile_device_submodel(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = mobile_device_submodel_service.GetMobileDeviceSubmodelRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_mobile_device_submodels_empty_call_rest(): + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_mobile_device_submodels), "__call__" + ) as call: + client.list_mobile_device_submodels(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = mobile_device_submodel_service.ListMobileDeviceSubmodelsRequest() + + assert args[0] == request_msg + + +def test_mobile_device_submodel_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.MobileDeviceSubmodelServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_mobile_device_submodel_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.ads.admanager_v1.services.mobile_device_submodel_service.transports.MobileDeviceSubmodelServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.MobileDeviceSubmodelServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "get_mobile_device_submodel", + "list_mobile_device_submodels", + "get_operation", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_mobile_device_submodel_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.ads.admanager_v1.services.mobile_device_submodel_service.transports.MobileDeviceSubmodelServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.MobileDeviceSubmodelServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id="octopus", + ) + + +def test_mobile_device_submodel_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.ads.admanager_v1.services.mobile_device_submodel_service.transports.MobileDeviceSubmodelServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.MobileDeviceSubmodelServiceTransport() + adc.assert_called_once() + + +def test_mobile_device_submodel_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + MobileDeviceSubmodelServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id=None, + ) + + +def test_mobile_device_submodel_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.MobileDeviceSubmodelServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_mobile_device_submodel_service_host_no_port(transport_name): + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_mobile_device_submodel_service_host_with_port(transport_name): + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_mobile_device_submodel_service_client_transport_session_collision( + transport_name, +): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = MobileDeviceSubmodelServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = MobileDeviceSubmodelServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.get_mobile_device_submodel._session + session2 = client2.transport.get_mobile_device_submodel._session + assert session1 != session2 + session1 = client1.transport.list_mobile_device_submodels._session + session2 = client2.transport.list_mobile_device_submodels._session + assert session1 != session2 + + +def test_mobile_device_path(): + network_code = "squid" + mobile_device = "clam" + expected = "networks/{network_code}/mobileDevices/{mobile_device}".format( + network_code=network_code, + mobile_device=mobile_device, + ) + actual = MobileDeviceSubmodelServiceClient.mobile_device_path( + network_code, mobile_device + ) + assert expected == actual + + +def test_parse_mobile_device_path(): + expected = { + "network_code": "whelk", + "mobile_device": "octopus", + } + path = MobileDeviceSubmodelServiceClient.mobile_device_path(**expected) + + # Check that the path construction is reversible. + actual = MobileDeviceSubmodelServiceClient.parse_mobile_device_path(path) + assert expected == actual + + +def test_mobile_device_submodel_path(): + network_code = "oyster" + mobile_device_submodel = "nudibranch" + expected = ( + "networks/{network_code}/mobileDeviceSubmodels/{mobile_device_submodel}".format( + network_code=network_code, + mobile_device_submodel=mobile_device_submodel, + ) + ) + actual = MobileDeviceSubmodelServiceClient.mobile_device_submodel_path( + network_code, mobile_device_submodel + ) + assert expected == actual + + +def test_parse_mobile_device_submodel_path(): + expected = { + "network_code": "cuttlefish", + "mobile_device_submodel": "mussel", + } + path = MobileDeviceSubmodelServiceClient.mobile_device_submodel_path(**expected) + + # Check that the path construction is reversible. + actual = MobileDeviceSubmodelServiceClient.parse_mobile_device_submodel_path(path) + assert expected == actual + + +def test_network_path(): + network_code = "winkle" + expected = "networks/{network_code}".format( + network_code=network_code, + ) + actual = MobileDeviceSubmodelServiceClient.network_path(network_code) + assert expected == actual + + +def test_parse_network_path(): + expected = { + "network_code": "nautilus", + } + path = MobileDeviceSubmodelServiceClient.network_path(**expected) + + # Check that the path construction is reversible. + actual = MobileDeviceSubmodelServiceClient.parse_network_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "scallop" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = MobileDeviceSubmodelServiceClient.common_billing_account_path( + billing_account + ) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "abalone", + } + path = MobileDeviceSubmodelServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = MobileDeviceSubmodelServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "squid" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = MobileDeviceSubmodelServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "clam", + } + path = MobileDeviceSubmodelServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = MobileDeviceSubmodelServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "whelk" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = MobileDeviceSubmodelServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "octopus", + } + path = MobileDeviceSubmodelServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = MobileDeviceSubmodelServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "oyster" + expected = "projects/{project}".format( + project=project, + ) + actual = MobileDeviceSubmodelServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nudibranch", + } + path = MobileDeviceSubmodelServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = MobileDeviceSubmodelServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "cuttlefish" + location = "mussel" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = MobileDeviceSubmodelServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "winkle", + "location": "nautilus", + } + path = MobileDeviceSubmodelServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = MobileDeviceSubmodelServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.MobileDeviceSubmodelServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.MobileDeviceSubmodelServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = MobileDeviceSubmodelServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_rest(): + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + ] + for transport in transports: + client = MobileDeviceSubmodelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + ( + MobileDeviceSubmodelServiceClient, + transports.MobileDeviceSubmodelServiceRestTransport, + ), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_placement_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_placement_service.py index 7deae354baee..abdaad628c0f 100644 --- a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_placement_service.py +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_placement_service.py @@ -52,6 +52,7 @@ from google.auth.exceptions import MutualTLSChannelError from google.longrunning import operations_pb2 # type: ignore from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore from google.protobuf import timestamp_pb2 # type: ignore from google.ads.admanager_v1.services.placement_service import ( @@ -1407,96 +1408,2579 @@ def test_list_placements_rest_pager(transport: str = "rest"): assert page_.raw_page.next_page_token == token -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.PlacementServiceRestTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): +def test_create_placement_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = PlacementServiceClient( credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + transport="rest", ) - # It is an error to provide a credentials file and a transport instance. - transport = transports.PlacementServiceRestTransport( + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.create_placement in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.create_placement + ] = mock_rpc + + request = {} + client.create_placement(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.create_placement(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_placement_rest_required_fields( + request_type=placement_service.CreatePlacementRequest, +): + transport_class = transports.PlacementServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_placement._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_placement._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = PlacementServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = PlacementServiceClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) + request = request_type(**request_init) - # It is an error to provide an api_key and a transport instance. + # Designate an appropriate value for the returned response. + return_value = placement_messages.Placement() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = placement_messages.Placement.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.create_placement(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_create_placement_rest_unset_required_fields(): transport = transports.PlacementServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_placement._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "placement", + ) + ) + ) + + +def test_create_placement_rest_flattened(): + client = PlacementServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = PlacementServiceClient( - client_options=options, - transport=transport, + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = placement_messages.Placement() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + placement=placement_messages.Placement(name="name_value"), ) + mock_args.update(sample_request) - # It is an error to provide an api_key and a credential. - options = client_options.ClientOptions() - options.api_key = "api_key" - with pytest.raises(ValueError): - client = PlacementServiceClient( - client_options=options, credentials=ga_credentials.AnonymousCredentials() + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = placement_messages.Placement.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.create_placement(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/placements" % client.transport._host, args[1] ) - # It is an error to provide scopes and a transport instance. - transport = transports.PlacementServiceRestTransport( + +def test_create_placement_rest_flattened_error(transport: str = "rest"): + client = PlacementServiceClient( credentials=ga_credentials.AnonymousCredentials(), + transport=transport, ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. with pytest.raises(ValueError): + client.create_placement( + placement_service.CreatePlacementRequest(), + parent="parent_value", + placement=placement_messages.Placement(name="name_value"), + ) + + +def test_update_placement_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: client = PlacementServiceClient( - client_options={"scopes": ["1", "2"]}, - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.update_placement in client._transport._wrapped_methods -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.update_placement + ] = mock_rpc + + request = {} + client.update_placement(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_placement(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_update_placement_rest_required_fields( + request_type=placement_service.UpdatePlacementRequest, +): + transport_class = transports.PlacementServiceRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_placement._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_placement._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = placement_messages.Placement() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = placement_messages.Placement.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.update_placement(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_placement_rest_unset_required_fields(): + transport = transports.PlacementServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_placement._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("updateMask",)) + & set( + ( + "placement", + "updateMask", + ) + ) + ) + + +def test_update_placement_rest_flattened(): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = placement_messages.Placement() + + # get arguments that satisfy an http rule for this method + sample_request = {"placement": {"name": "networks/sample1/placements/sample2"}} + + # get truthy value for each flattened field + mock_args = dict( + placement=placement_messages.Placement(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = placement_messages.Placement.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.update_placement(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{placement.name=networks/*/placements/*}" % client.transport._host, + args[1], + ) + + +def test_update_placement_rest_flattened_error(transport: str = "rest"): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_placement( + placement_service.UpdatePlacementRequest(), + placement=placement_messages.Placement(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_batch_create_placements_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_create_placements + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_create_placements + ] = mock_rpc + + request = {} + client.batch_create_placements(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_create_placements(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_create_placements_rest_required_fields( + request_type=placement_service.BatchCreatePlacementsRequest, +): + transport_class = transports.PlacementServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_create_placements._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_create_placements._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = placement_service.BatchCreatePlacementsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = placement_service.BatchCreatePlacementsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_create_placements(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_create_placements_rest_unset_required_fields(): + transport = transports.PlacementServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_create_placements._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "requests", + ) + ) + ) + + +def test_batch_create_placements_rest_flattened(): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = placement_service.BatchCreatePlacementsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + requests=[placement_service.CreatePlacementRequest(parent="parent_value")], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = placement_service.BatchCreatePlacementsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.batch_create_placements(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/placements:batchCreate" % client.transport._host, + args[1], + ) + + +def test_batch_create_placements_rest_flattened_error(transport: str = "rest"): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_create_placements( + placement_service.BatchCreatePlacementsRequest(), + parent="parent_value", + requests=[placement_service.CreatePlacementRequest(parent="parent_value")], + ) + + +def test_batch_update_placements_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_update_placements + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_update_placements + ] = mock_rpc + + request = {} + client.batch_update_placements(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_update_placements(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_update_placements_rest_required_fields( + request_type=placement_service.BatchUpdatePlacementsRequest, +): + transport_class = transports.PlacementServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_update_placements._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_update_placements._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = placement_service.BatchUpdatePlacementsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = placement_service.BatchUpdatePlacementsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_update_placements(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_update_placements_rest_unset_required_fields(): + transport = transports.PlacementServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_update_placements._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "requests", + ) + ) + ) + + +def test_batch_update_placements_rest_flattened(): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = placement_service.BatchUpdatePlacementsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + requests=[ + placement_service.UpdatePlacementRequest( + placement=placement_messages.Placement(name="name_value") + ) + ], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = placement_service.BatchUpdatePlacementsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.batch_update_placements(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/placements:batchUpdate" % client.transport._host, + args[1], + ) + + +def test_batch_update_placements_rest_flattened_error(transport: str = "rest"): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_update_placements( + placement_service.BatchUpdatePlacementsRequest(), + parent="parent_value", + requests=[ + placement_service.UpdatePlacementRequest( + placement=placement_messages.Placement(name="name_value") + ) + ], + ) + + +def test_batch_activate_placements_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_activate_placements + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_activate_placements + ] = mock_rpc + + request = {} + client.batch_activate_placements(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_activate_placements(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_activate_placements_rest_required_fields( + request_type=placement_service.BatchActivatePlacementsRequest, +): + transport_class = transports.PlacementServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["names"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_activate_placements._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + jsonified_request["names"] = "names_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_activate_placements._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "names" in jsonified_request + assert jsonified_request["names"] == "names_value" + + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = placement_service.BatchActivatePlacementsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = placement_service.BatchActivatePlacementsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_activate_placements(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_activate_placements_rest_unset_required_fields(): + transport = transports.PlacementServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_activate_placements._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "names", + ) + ) + ) + + +def test_batch_activate_placements_rest_flattened(): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = placement_service.BatchActivatePlacementsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + names=["names_value"], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = placement_service.BatchActivatePlacementsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.batch_activate_placements(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/placements:batchActivate" + % client.transport._host, + args[1], + ) + + +def test_batch_activate_placements_rest_flattened_error(transport: str = "rest"): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_activate_placements( + placement_service.BatchActivatePlacementsRequest(), + parent="parent_value", + names=["names_value"], + ) + + +def test_batch_deactivate_placements_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_deactivate_placements + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_deactivate_placements + ] = mock_rpc + + request = {} + client.batch_deactivate_placements(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_deactivate_placements(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_deactivate_placements_rest_required_fields( + request_type=placement_service.BatchDeactivatePlacementsRequest, +): + transport_class = transports.PlacementServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["names"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_deactivate_placements._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + jsonified_request["names"] = "names_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_deactivate_placements._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "names" in jsonified_request + assert jsonified_request["names"] == "names_value" + + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = placement_service.BatchDeactivatePlacementsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = placement_service.BatchDeactivatePlacementsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_deactivate_placements(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_deactivate_placements_rest_unset_required_fields(): + transport = transports.PlacementServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_deactivate_placements._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "names", + ) + ) + ) + + +def test_batch_deactivate_placements_rest_flattened(): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = placement_service.BatchDeactivatePlacementsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + names=["names_value"], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = placement_service.BatchDeactivatePlacementsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.batch_deactivate_placements(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/placements:batchDeactivate" + % client.transport._host, + args[1], + ) + + +def test_batch_deactivate_placements_rest_flattened_error(transport: str = "rest"): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_deactivate_placements( + placement_service.BatchDeactivatePlacementsRequest(), + parent="parent_value", + names=["names_value"], + ) + + +def test_batch_archive_placements_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_archive_placements + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_archive_placements + ] = mock_rpc + + request = {} + client.batch_archive_placements(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_archive_placements(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_archive_placements_rest_required_fields( + request_type=placement_service.BatchArchivePlacementsRequest, +): + transport_class = transports.PlacementServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["names"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_archive_placements._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + jsonified_request["names"] = "names_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_archive_placements._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "names" in jsonified_request + assert jsonified_request["names"] == "names_value" + + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = placement_service.BatchArchivePlacementsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = placement_service.BatchArchivePlacementsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_archive_placements(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_archive_placements_rest_unset_required_fields(): + transport = transports.PlacementServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_archive_placements._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "names", + ) + ) + ) + + +def test_batch_archive_placements_rest_flattened(): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = placement_service.BatchArchivePlacementsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + names=["names_value"], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = placement_service.BatchArchivePlacementsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.batch_archive_placements(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/placements:batchArchive" + % client.transport._host, + args[1], + ) + + +def test_batch_archive_placements_rest_flattened_error(transport: str = "rest"): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_archive_placements( + placement_service.BatchArchivePlacementsRequest(), + parent="parent_value", + names=["names_value"], + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.PlacementServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.PlacementServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PlacementServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.PlacementServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = PlacementServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = PlacementServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.PlacementServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PlacementServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.PlacementServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = PlacementServiceClient(transport=transport) + assert client.transport is transport + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.PlacementServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_rest(): + transport = PlacementServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_placement_rest_bad_request( + request_type=placement_service.GetPlacementRequest, +): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/placements/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_placement(request) + + +@pytest.mark.parametrize( + "request_type", + [ + placement_service.GetPlacementRequest, + dict, + ], +) +def test_get_placement_rest_call_success(request_type): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/placements/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = placement_messages.Placement( + name="name_value", + placement_id=1253, + display_name="display_name_value", + description="description_value", + placement_code="placement_code_value", + status=placement_enums.PlacementStatusEnum.PlacementStatus.ACTIVE, + targeted_ad_units=["targeted_ad_units_value"], + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = placement_messages.Placement.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_placement(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, placement_messages.Placement) + assert response.name == "name_value" + assert response.placement_id == 1253 + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.placement_code == "placement_code_value" + assert response.status == placement_enums.PlacementStatusEnum.PlacementStatus.ACTIVE + assert response.targeted_ad_units == ["targeted_ad_units_value"] + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_placement_rest_interceptors(null_interceptor): + transport = transports.PlacementServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.PlacementServiceRestInterceptor(), + ) + client = PlacementServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.PlacementServiceRestInterceptor, "post_get_placement" + ) as post, mock.patch.object( + transports.PlacementServiceRestInterceptor, "post_get_placement_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.PlacementServiceRestInterceptor, "pre_get_placement" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = placement_service.GetPlacementRequest.pb( + placement_service.GetPlacementRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = placement_messages.Placement.to_json( + placement_messages.Placement() + ) + req.return_value.content = return_value + + request = placement_service.GetPlacementRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = placement_messages.Placement() + post_with_metadata.return_value = placement_messages.Placement(), metadata + + client.get_placement( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_placements_rest_bad_request( + request_type=placement_service.ListPlacementsRequest, +): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_placements(request) + + +@pytest.mark.parametrize( + "request_type", + [ + placement_service.ListPlacementsRequest, + dict, + ], +) +def test_list_placements_rest_call_success(request_type): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = placement_service.ListPlacementsResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = placement_service.ListPlacementsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_placements(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListPlacementsPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_placements_rest_interceptors(null_interceptor): + transport = transports.PlacementServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.PlacementServiceRestInterceptor(), + ) + client = PlacementServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.PlacementServiceRestInterceptor, "post_list_placements" + ) as post, mock.patch.object( + transports.PlacementServiceRestInterceptor, "post_list_placements_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.PlacementServiceRestInterceptor, "pre_list_placements" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = placement_service.ListPlacementsRequest.pb( + placement_service.ListPlacementsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = placement_service.ListPlacementsResponse.to_json( + placement_service.ListPlacementsResponse() + ) + req.return_value.content = return_value + + request = placement_service.ListPlacementsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = placement_service.ListPlacementsResponse() + post_with_metadata.return_value = ( + placement_service.ListPlacementsResponse(), + metadata, + ) + + client.list_placements( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_create_placement_rest_bad_request( + request_type=placement_service.CreatePlacementRequest, +): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.create_placement(request) + + +@pytest.mark.parametrize( + "request_type", + [ + placement_service.CreatePlacementRequest, + dict, + ], +) +def test_create_placement_rest_call_success(request_type): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request_init["placement"] = { + "name": "name_value", + "placement_id": 1253, + "display_name": "display_name_value", + "description": "description_value", + "placement_code": "placement_code_value", + "status": 1, + "targeted_ad_units": ["targeted_ad_units_value1", "targeted_ad_units_value2"], + "update_time": {"seconds": 751, "nanos": 543}, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = placement_service.CreatePlacementRequest.meta.fields["placement"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["placement"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["placement"][field])): + del request_init["placement"][field][i][subfield] + else: + del request_init["placement"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = placement_messages.Placement( + name="name_value", + placement_id=1253, + display_name="display_name_value", + description="description_value", + placement_code="placement_code_value", + status=placement_enums.PlacementStatusEnum.PlacementStatus.ACTIVE, + targeted_ad_units=["targeted_ad_units_value"], + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = placement_messages.Placement.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.create_placement(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, placement_messages.Placement) + assert response.name == "name_value" + assert response.placement_id == 1253 + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.placement_code == "placement_code_value" + assert response.status == placement_enums.PlacementStatusEnum.PlacementStatus.ACTIVE + assert response.targeted_ad_units == ["targeted_ad_units_value"] + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_placement_rest_interceptors(null_interceptor): + transport = transports.PlacementServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.PlacementServiceRestInterceptor(), + ) + client = PlacementServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.PlacementServiceRestInterceptor, "post_create_placement" + ) as post, mock.patch.object( + transports.PlacementServiceRestInterceptor, + "post_create_placement_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.PlacementServiceRestInterceptor, "pre_create_placement" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = placement_service.CreatePlacementRequest.pb( + placement_service.CreatePlacementRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = placement_messages.Placement.to_json( + placement_messages.Placement() + ) + req.return_value.content = return_value + + request = placement_service.CreatePlacementRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = placement_messages.Placement() + post_with_metadata.return_value = placement_messages.Placement(), metadata + + client.create_placement( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_update_placement_rest_bad_request( + request_type=placement_service.UpdatePlacementRequest, +): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"placement": {"name": "networks/sample1/placements/sample2"}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.update_placement(request) + + +@pytest.mark.parametrize( + "request_type", + [ + placement_service.UpdatePlacementRequest, + dict, + ], +) +def test_update_placement_rest_call_success(request_type): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"placement": {"name": "networks/sample1/placements/sample2"}} + request_init["placement"] = { + "name": "networks/sample1/placements/sample2", + "placement_id": 1253, + "display_name": "display_name_value", + "description": "description_value", + "placement_code": "placement_code_value", + "status": 1, + "targeted_ad_units": ["targeted_ad_units_value1", "targeted_ad_units_value2"], + "update_time": {"seconds": 751, "nanos": 543}, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = placement_service.UpdatePlacementRequest.meta.fields["placement"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["placement"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["placement"][field])): + del request_init["placement"][field][i][subfield] + else: + del request_init["placement"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = placement_messages.Placement( + name="name_value", + placement_id=1253, + display_name="display_name_value", + description="description_value", + placement_code="placement_code_value", + status=placement_enums.PlacementStatusEnum.PlacementStatus.ACTIVE, + targeted_ad_units=["targeted_ad_units_value"], + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = placement_messages.Placement.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.update_placement(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, placement_messages.Placement) + assert response.name == "name_value" + assert response.placement_id == 1253 + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.placement_code == "placement_code_value" + assert response.status == placement_enums.PlacementStatusEnum.PlacementStatus.ACTIVE + assert response.targeted_ad_units == ["targeted_ad_units_value"] + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_placement_rest_interceptors(null_interceptor): + transport = transports.PlacementServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.PlacementServiceRestInterceptor(), + ) + client = PlacementServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.PlacementServiceRestInterceptor, "post_update_placement" + ) as post, mock.patch.object( + transports.PlacementServiceRestInterceptor, + "post_update_placement_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.PlacementServiceRestInterceptor, "pre_update_placement" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = placement_service.UpdatePlacementRequest.pb( + placement_service.UpdatePlacementRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = placement_messages.Placement.to_json( + placement_messages.Placement() + ) + req.return_value.content = return_value + + request = placement_service.UpdatePlacementRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = placement_messages.Placement() + post_with_metadata.return_value = placement_messages.Placement(), metadata + + client.update_placement( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_batch_create_placements_rest_bad_request( + request_type=placement_service.BatchCreatePlacementsRequest, +): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.batch_create_placements(request) + + +@pytest.mark.parametrize( + "request_type", + [ + placement_service.BatchCreatePlacementsRequest, + dict, + ], +) +def test_batch_create_placements_rest_call_success(request_type): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = placement_service.BatchCreatePlacementsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = placement_service.BatchCreatePlacementsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.batch_create_placements(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, placement_service.BatchCreatePlacementsResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_create_placements_rest_interceptors(null_interceptor): + transport = transports.PlacementServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.PlacementServiceRestInterceptor(), + ) + client = PlacementServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.PlacementServiceRestInterceptor, "post_batch_create_placements" + ) as post, mock.patch.object( + transports.PlacementServiceRestInterceptor, + "post_batch_create_placements_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.PlacementServiceRestInterceptor, "pre_batch_create_placements" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = placement_service.BatchCreatePlacementsRequest.pb( + placement_service.BatchCreatePlacementsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = placement_service.BatchCreatePlacementsResponse.to_json( + placement_service.BatchCreatePlacementsResponse() + ) + req.return_value.content = return_value + + request = placement_service.BatchCreatePlacementsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = placement_service.BatchCreatePlacementsResponse() + post_with_metadata.return_value = ( + placement_service.BatchCreatePlacementsResponse(), + metadata, + ) + + client.batch_create_placements( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_batch_update_placements_rest_bad_request( + request_type=placement_service.BatchUpdatePlacementsRequest, +): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.batch_update_placements(request) + + +@pytest.mark.parametrize( + "request_type", + [ + placement_service.BatchUpdatePlacementsRequest, + dict, + ], +) +def test_batch_update_placements_rest_call_success(request_type): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = placement_service.BatchUpdatePlacementsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = placement_service.BatchUpdatePlacementsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.batch_update_placements(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, placement_service.BatchUpdatePlacementsResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_update_placements_rest_interceptors(null_interceptor): + transport = transports.PlacementServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.PlacementServiceRestInterceptor(), + ) + client = PlacementServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.PlacementServiceRestInterceptor, "post_batch_update_placements" + ) as post, mock.patch.object( + transports.PlacementServiceRestInterceptor, + "post_batch_update_placements_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.PlacementServiceRestInterceptor, "pre_batch_update_placements" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = placement_service.BatchUpdatePlacementsRequest.pb( + placement_service.BatchUpdatePlacementsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = placement_service.BatchUpdatePlacementsResponse.to_json( + placement_service.BatchUpdatePlacementsResponse() + ) + req.return_value.content = return_value + + request = placement_service.BatchUpdatePlacementsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = placement_service.BatchUpdatePlacementsResponse() + post_with_metadata.return_value = ( + placement_service.BatchUpdatePlacementsResponse(), + metadata, + ) + + client.batch_update_placements( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_batch_activate_placements_rest_bad_request( + request_type=placement_service.BatchActivatePlacementsRequest, +): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.batch_activate_placements(request) + + +@pytest.mark.parametrize( + "request_type", + [ + placement_service.BatchActivatePlacementsRequest, + dict, + ], +) +def test_batch_activate_placements_rest_call_success(request_type): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = placement_service.BatchActivatePlacementsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = placement_service.BatchActivatePlacementsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.batch_activate_placements(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, placement_service.BatchActivatePlacementsResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_activate_placements_rest_interceptors(null_interceptor): transport = transports.PlacementServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.PlacementServiceRestInterceptor(), ) client = PlacementServiceClient(transport=transport) - assert client.transport is transport + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.PlacementServiceRestInterceptor, "post_batch_activate_placements" + ) as post, mock.patch.object( + transports.PlacementServiceRestInterceptor, + "post_batch_activate_placements_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.PlacementServiceRestInterceptor, "pre_batch_activate_placements" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = placement_service.BatchActivatePlacementsRequest.pb( + placement_service.BatchActivatePlacementsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } -@pytest.mark.parametrize( - "transport_class", - [ - transports.PlacementServiceRestTransport, - ], -) -def test_transport_adc(transport_class): - # Test default credentials are used if not provided. - with mock.patch.object(google.auth, "default") as adc: - adc.return_value = (ga_credentials.AnonymousCredentials(), None) - transport_class() - adc.assert_called_once() + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = placement_service.BatchActivatePlacementsResponse.to_json( + placement_service.BatchActivatePlacementsResponse() + ) + req.return_value.content = return_value + request = placement_service.BatchActivatePlacementsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = placement_service.BatchActivatePlacementsResponse() + post_with_metadata.return_value = ( + placement_service.BatchActivatePlacementsResponse(), + metadata, + ) -def test_transport_kind_rest(): - transport = PlacementServiceClient.get_transport_class("rest")( - credentials=ga_credentials.AnonymousCredentials() - ) - assert transport.kind == "rest" + client.batch_activate_placements( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() -def test_get_placement_rest_bad_request( - request_type=placement_service.GetPlacementRequest, +def test_batch_deactivate_placements_rest_bad_request( + request_type=placement_service.BatchDeactivatePlacementsRequest, ): client = PlacementServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "networks/sample1/placements/sample2"} + request_init = {"parent": "networks/sample1"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -1511,63 +3995,50 @@ def test_get_placement_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.get_placement(request) + client.batch_deactivate_placements(request) @pytest.mark.parametrize( "request_type", [ - placement_service.GetPlacementRequest, + placement_service.BatchDeactivatePlacementsRequest, dict, ], ) -def test_get_placement_rest_call_success(request_type): +def test_batch_deactivate_placements_rest_call_success(request_type): client = PlacementServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) # send a request that will satisfy transcoding - request_init = {"name": "networks/sample1/placements/sample2"} + request_init = {"parent": "networks/sample1"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = placement_messages.Placement( - name="name_value", - placement_id=1253, - display_name="display_name_value", - description="description_value", - placement_code="placement_code_value", - status=placement_enums.PlacementStatusEnum.PlacementStatus.ACTIVE, - targeted_ad_units=["targeted_ad_units_value"], - ) + return_value = placement_service.BatchDeactivatePlacementsResponse() # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 # Convert return value to protobuf type - return_value = placement_messages.Placement.pb(return_value) + return_value = placement_service.BatchDeactivatePlacementsResponse.pb( + return_value + ) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.get_placement(request) + response = client.batch_deactivate_placements(request) # Establish that the response is the type that we expect. - assert isinstance(response, placement_messages.Placement) - assert response.name == "name_value" - assert response.placement_id == 1253 - assert response.display_name == "display_name_value" - assert response.description == "description_value" - assert response.placement_code == "placement_code_value" - assert response.status == placement_enums.PlacementStatusEnum.PlacementStatus.ACTIVE - assert response.targeted_ad_units == ["targeted_ad_units_value"] + assert isinstance(response, placement_service.BatchDeactivatePlacementsResponse) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_placement_rest_interceptors(null_interceptor): +def test_batch_deactivate_placements_rest_interceptors(null_interceptor): transport = transports.PlacementServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -1581,17 +4052,18 @@ def test_get_placement_rest_interceptors(null_interceptor): ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.PlacementServiceRestInterceptor, "post_get_placement" + transports.PlacementServiceRestInterceptor, "post_batch_deactivate_placements" ) as post, mock.patch.object( - transports.PlacementServiceRestInterceptor, "post_get_placement_with_metadata" + transports.PlacementServiceRestInterceptor, + "post_batch_deactivate_placements_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.PlacementServiceRestInterceptor, "pre_get_placement" + transports.PlacementServiceRestInterceptor, "pre_batch_deactivate_placements" ) as pre: pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = placement_service.GetPlacementRequest.pb( - placement_service.GetPlacementRequest() + pb_message = placement_service.BatchDeactivatePlacementsRequest.pb( + placement_service.BatchDeactivatePlacementsRequest() ) transcode.return_value = { "method": "post", @@ -1603,21 +4075,24 @@ def test_get_placement_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = placement_messages.Placement.to_json( - placement_messages.Placement() + return_value = placement_service.BatchDeactivatePlacementsResponse.to_json( + placement_service.BatchDeactivatePlacementsResponse() ) req.return_value.content = return_value - request = placement_service.GetPlacementRequest() + request = placement_service.BatchDeactivatePlacementsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = placement_messages.Placement() - post_with_metadata.return_value = placement_messages.Placement(), metadata + post.return_value = placement_service.BatchDeactivatePlacementsResponse() + post_with_metadata.return_value = ( + placement_service.BatchDeactivatePlacementsResponse(), + metadata, + ) - client.get_placement( + client.batch_deactivate_placements( request, metadata=[ ("key", "val"), @@ -1630,8 +4105,8 @@ def test_get_placement_rest_interceptors(null_interceptor): post_with_metadata.assert_called_once() -def test_list_placements_rest_bad_request( - request_type=placement_service.ListPlacementsRequest, +def test_batch_archive_placements_rest_bad_request( + request_type=placement_service.BatchArchivePlacementsRequest, ): client = PlacementServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" @@ -1652,17 +4127,17 @@ def test_list_placements_rest_bad_request( response_value.request = mock.Mock() req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - client.list_placements(request) + client.batch_archive_placements(request) @pytest.mark.parametrize( "request_type", [ - placement_service.ListPlacementsRequest, + placement_service.BatchArchivePlacementsRequest, dict, ], ) -def test_list_placements_rest_call_success(request_type): +def test_batch_archive_placements_rest_call_success(request_type): client = PlacementServiceClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -1674,31 +4149,26 @@ def test_list_placements_rest_call_success(request_type): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = placement_service.ListPlacementsResponse( - next_page_token="next_page_token_value", - total_size=1086, - ) + return_value = placement_service.BatchArchivePlacementsResponse() # Wrap the value into a proper Response obj response_value = mock.Mock() response_value.status_code = 200 # Convert return value to protobuf type - return_value = placement_service.ListPlacementsResponse.pb(return_value) + return_value = placement_service.BatchArchivePlacementsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value.content = json_return_value.encode("UTF-8") req.return_value = response_value req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - response = client.list_placements(request) + response = client.batch_archive_placements(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListPlacementsPager) - assert response.next_page_token == "next_page_token_value" - assert response.total_size == 1086 + assert isinstance(response, placement_service.BatchArchivePlacementsResponse) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_placements_rest_interceptors(null_interceptor): +def test_batch_archive_placements_rest_interceptors(null_interceptor): transport = transports.PlacementServiceRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -1712,17 +4182,18 @@ def test_list_placements_rest_interceptors(null_interceptor): ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.PlacementServiceRestInterceptor, "post_list_placements" + transports.PlacementServiceRestInterceptor, "post_batch_archive_placements" ) as post, mock.patch.object( - transports.PlacementServiceRestInterceptor, "post_list_placements_with_metadata" + transports.PlacementServiceRestInterceptor, + "post_batch_archive_placements_with_metadata", ) as post_with_metadata, mock.patch.object( - transports.PlacementServiceRestInterceptor, "pre_list_placements" + transports.PlacementServiceRestInterceptor, "pre_batch_archive_placements" ) as pre: pre.assert_not_called() post.assert_not_called() post_with_metadata.assert_not_called() - pb_message = placement_service.ListPlacementsRequest.pb( - placement_service.ListPlacementsRequest() + pb_message = placement_service.BatchArchivePlacementsRequest.pb( + placement_service.BatchArchivePlacementsRequest() ) transcode.return_value = { "method": "post", @@ -1734,24 +4205,24 @@ def test_list_placements_rest_interceptors(null_interceptor): req.return_value = mock.Mock() req.return_value.status_code = 200 req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} - return_value = placement_service.ListPlacementsResponse.to_json( - placement_service.ListPlacementsResponse() + return_value = placement_service.BatchArchivePlacementsResponse.to_json( + placement_service.BatchArchivePlacementsResponse() ) req.return_value.content = return_value - request = placement_service.ListPlacementsRequest() + request = placement_service.BatchArchivePlacementsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = placement_service.ListPlacementsResponse() + post.return_value = placement_service.BatchArchivePlacementsResponse() post_with_metadata.return_value = ( - placement_service.ListPlacementsResponse(), + placement_service.BatchArchivePlacementsResponse(), metadata, ) - client.list_placements( + client.batch_archive_placements( request, metadata=[ ("key", "val"), @@ -1873,6 +4344,156 @@ def test_list_placements_empty_call_rest(): assert args[0] == request_msg +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_placement_empty_call_rest(): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_placement), "__call__") as call: + client.create_placement(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = placement_service.CreatePlacementRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_placement_empty_call_rest(): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_placement), "__call__") as call: + client.update_placement(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = placement_service.UpdatePlacementRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_create_placements_empty_call_rest(): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_placements), "__call__" + ) as call: + client.batch_create_placements(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = placement_service.BatchCreatePlacementsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_update_placements_empty_call_rest(): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_update_placements), "__call__" + ) as call: + client.batch_update_placements(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = placement_service.BatchUpdatePlacementsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_activate_placements_empty_call_rest(): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_activate_placements), "__call__" + ) as call: + client.batch_activate_placements(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = placement_service.BatchActivatePlacementsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_deactivate_placements_empty_call_rest(): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_deactivate_placements), "__call__" + ) as call: + client.batch_deactivate_placements(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = placement_service.BatchDeactivatePlacementsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_archive_placements_empty_call_rest(): + client = PlacementServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_archive_placements), "__call__" + ) as call: + client.batch_archive_placements(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = placement_service.BatchArchivePlacementsRequest() + + assert args[0] == request_msg + + def test_placement_service_base_transport_error(): # Passing both a credentials object and credentials_file should raise an error with pytest.raises(core_exceptions.DuplicateCredentialArgs): @@ -1897,6 +4518,13 @@ def test_placement_service_base_transport(): methods = ( "get_placement", "list_placements", + "create_placement", + "update_placement", + "batch_create_placements", + "batch_update_placements", + "batch_activate_placements", + "batch_deactivate_placements", + "batch_archive_placements", "get_operation", ) for method in methods: @@ -2035,6 +4663,27 @@ def test_placement_service_client_transport_session_collision(transport_name): session1 = client1.transport.list_placements._session session2 = client2.transport.list_placements._session assert session1 != session2 + session1 = client1.transport.create_placement._session + session2 = client2.transport.create_placement._session + assert session1 != session2 + session1 = client1.transport.update_placement._session + session2 = client2.transport.update_placement._session + assert session1 != session2 + session1 = client1.transport.batch_create_placements._session + session2 = client2.transport.batch_create_placements._session + assert session1 != session2 + session1 = client1.transport.batch_update_placements._session + session2 = client2.transport.batch_update_placements._session + assert session1 != session2 + session1 = client1.transport.batch_activate_placements._session + session2 = client2.transport.batch_activate_placements._session + assert session1 != session2 + session1 = client1.transport.batch_deactivate_placements._session + session2 = client2.transport.batch_deactivate_placements._session + assert session1 != session2 + session1 = client1.transport.batch_archive_placements._session + session2 = client2.transport.batch_archive_placements._session + assert session1 != session2 def test_ad_unit_path(): diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_private_auction_deal_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_private_auction_deal_service.py index 79d9667dc0e7..ecbcc47b9f80 100644 --- a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_private_auction_deal_service.py +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_private_auction_deal_service.py @@ -2322,6 +2322,36 @@ def test_create_private_auction_deal_rest_call_success(request_type): "excluded_bandwidth_groups_value2", ], }, + "browser_targeting": { + "targeted_browsers": [ + "targeted_browsers_value1", + "targeted_browsers_value2", + ], + "excluded_browsers": [ + "excluded_browsers_value1", + "excluded_browsers_value2", + ], + }, + "browser_language_targeting": { + "targeted_browser_languages": [ + "targeted_browser_languages_value1", + "targeted_browser_languages_value2", + ], + "excluded_browser_languages": [ + "excluded_browser_languages_value1", + "excluded_browser_languages_value2", + ], + }, + "device_capability_targeting": { + "targeted_capabilities": [ + "targeted_capabilities_value1", + "targeted_capabilities_value2", + ], + "excluded_capabilities": [ + "excluded_capabilities_value1", + "excluded_capabilities_value2", + ], + }, "device_category_targeting": { "targeted_categories": [ "targeted_categories_value1", @@ -2332,6 +2362,42 @@ def test_create_private_auction_deal_rest_call_success(request_type): "excluded_categories_value2", ], }, + "device_manufacturer_targeting": { + "targeted_device_manufacturers": [ + "targeted_device_manufacturers_value1", + "targeted_device_manufacturers_value2", + ], + "excluded_device_manufacturers": [ + "excluded_device_manufacturers_value1", + "excluded_device_manufacturers_value2", + ], + "targeted_mobile_devices": [ + "targeted_mobile_devices_value1", + "targeted_mobile_devices_value2", + ], + "excluded_mobile_devices": [ + "excluded_mobile_devices_value1", + "excluded_mobile_devices_value2", + ], + "targeted_mobile_device_submodels": [ + "targeted_mobile_device_submodels_value1", + "targeted_mobile_device_submodels_value2", + ], + "excluded_mobile_device_submodels": [ + "excluded_mobile_device_submodels_value1", + "excluded_mobile_device_submodels_value2", + ], + }, + "mobile_carrier_targeting": { + "targeted_mobile_carriers": [ + "targeted_mobile_carriers_value1", + "targeted_mobile_carriers_value2", + ], + "excluded_mobile_carriers": [ + "excluded_mobile_carriers_value1", + "excluded_mobile_carriers_value2", + ], + }, "operating_system_targeting": { "targeted_operating_systems": [ "targeted_operating_systems_value1", @@ -2374,7 +2440,25 @@ def test_create_private_auction_deal_rest_call_success(request_type): "custom_targeting_values_value2", ], } - ] + ], + "audience_segment_targetings": [ + { + "negative": True, + "audience_segments": [ + "audience_segments_value1", + "audience_segments_value2", + ], + } + ], + "cms_metadata_targetings": [ + { + "negative": True, + "cms_metadata_values": [ + "cms_metadata_values_value1", + "cms_metadata_values_value2", + ], + } + ], } ] }, @@ -2400,6 +2484,36 @@ def test_create_private_auction_deal_rest_call_success(request_type): ] }, "data_segment_targeting": {"has_data_segment_targeting": True}, + "content_targeting": { + "targeted_content": [ + "targeted_content_value1", + "targeted_content_value2", + ], + "excluded_content": [ + "excluded_content_value1", + "excluded_content_value2", + ], + "targeted_content_bundles": [ + "targeted_content_bundles_value1", + "targeted_content_bundles_value2", + ], + "excluded_content_bundles": [ + "excluded_content_bundles_value1", + "excluded_content_bundles_value2", + ], + }, + "mobile_application_targeting": { + "first_party_targeting": { + "targeted_applications": [ + "targeted_applications_value1", + "targeted_applications_value2", + ], + "excluded_applications": [ + "excluded_applications_value1", + "excluded_applications_value2", + ], + } + }, }, "end_time": {"seconds": 751, "nanos": 543}, "floor_price": { @@ -2675,6 +2789,36 @@ def test_update_private_auction_deal_rest_call_success(request_type): "excluded_bandwidth_groups_value2", ], }, + "browser_targeting": { + "targeted_browsers": [ + "targeted_browsers_value1", + "targeted_browsers_value2", + ], + "excluded_browsers": [ + "excluded_browsers_value1", + "excluded_browsers_value2", + ], + }, + "browser_language_targeting": { + "targeted_browser_languages": [ + "targeted_browser_languages_value1", + "targeted_browser_languages_value2", + ], + "excluded_browser_languages": [ + "excluded_browser_languages_value1", + "excluded_browser_languages_value2", + ], + }, + "device_capability_targeting": { + "targeted_capabilities": [ + "targeted_capabilities_value1", + "targeted_capabilities_value2", + ], + "excluded_capabilities": [ + "excluded_capabilities_value1", + "excluded_capabilities_value2", + ], + }, "device_category_targeting": { "targeted_categories": [ "targeted_categories_value1", @@ -2685,6 +2829,42 @@ def test_update_private_auction_deal_rest_call_success(request_type): "excluded_categories_value2", ], }, + "device_manufacturer_targeting": { + "targeted_device_manufacturers": [ + "targeted_device_manufacturers_value1", + "targeted_device_manufacturers_value2", + ], + "excluded_device_manufacturers": [ + "excluded_device_manufacturers_value1", + "excluded_device_manufacturers_value2", + ], + "targeted_mobile_devices": [ + "targeted_mobile_devices_value1", + "targeted_mobile_devices_value2", + ], + "excluded_mobile_devices": [ + "excluded_mobile_devices_value1", + "excluded_mobile_devices_value2", + ], + "targeted_mobile_device_submodels": [ + "targeted_mobile_device_submodels_value1", + "targeted_mobile_device_submodels_value2", + ], + "excluded_mobile_device_submodels": [ + "excluded_mobile_device_submodels_value1", + "excluded_mobile_device_submodels_value2", + ], + }, + "mobile_carrier_targeting": { + "targeted_mobile_carriers": [ + "targeted_mobile_carriers_value1", + "targeted_mobile_carriers_value2", + ], + "excluded_mobile_carriers": [ + "excluded_mobile_carriers_value1", + "excluded_mobile_carriers_value2", + ], + }, "operating_system_targeting": { "targeted_operating_systems": [ "targeted_operating_systems_value1", @@ -2727,7 +2907,25 @@ def test_update_private_auction_deal_rest_call_success(request_type): "custom_targeting_values_value2", ], } - ] + ], + "audience_segment_targetings": [ + { + "negative": True, + "audience_segments": [ + "audience_segments_value1", + "audience_segments_value2", + ], + } + ], + "cms_metadata_targetings": [ + { + "negative": True, + "cms_metadata_values": [ + "cms_metadata_values_value1", + "cms_metadata_values_value2", + ], + } + ], } ] }, @@ -2753,6 +2951,36 @@ def test_update_private_auction_deal_rest_call_success(request_type): ] }, "data_segment_targeting": {"has_data_segment_targeting": True}, + "content_targeting": { + "targeted_content": [ + "targeted_content_value1", + "targeted_content_value2", + ], + "excluded_content": [ + "excluded_content_value1", + "excluded_content_value2", + ], + "targeted_content_bundles": [ + "targeted_content_bundles_value1", + "targeted_content_bundles_value2", + ], + "excluded_content_bundles": [ + "excluded_content_bundles_value1", + "excluded_content_bundles_value2", + ], + }, + "mobile_application_targeting": { + "first_party_targeting": { + "targeted_applications": [ + "targeted_applications_value1", + "targeted_applications_value2", + ], + "excluded_applications": [ + "excluded_applications_value1", + "excluded_applications_value2", + ], + } + }, }, "end_time": {"seconds": 751, "nanos": 543}, "floor_price": { @@ -3316,9 +3544,57 @@ def test_parse_ad_unit_path(): assert expected == actual -def test_bandwidth_group_path(): +def test_application_path(): network_code = "oyster" - bandwidth_group = "nudibranch" + application = "nudibranch" + expected = "networks/{network_code}/applications/{application}".format( + network_code=network_code, + application=application, + ) + actual = PrivateAuctionDealServiceClient.application_path(network_code, application) + assert expected == actual + + +def test_parse_application_path(): + expected = { + "network_code": "cuttlefish", + "application": "mussel", + } + path = PrivateAuctionDealServiceClient.application_path(**expected) + + # Check that the path construction is reversible. + actual = PrivateAuctionDealServiceClient.parse_application_path(path) + assert expected == actual + + +def test_audience_segment_path(): + network_code = "winkle" + audience_segment = "nautilus" + expected = "networks/{network_code}/audienceSegments/{audience_segment}".format( + network_code=network_code, + audience_segment=audience_segment, + ) + actual = PrivateAuctionDealServiceClient.audience_segment_path( + network_code, audience_segment + ) + assert expected == actual + + +def test_parse_audience_segment_path(): + expected = { + "network_code": "scallop", + "audience_segment": "abalone", + } + path = PrivateAuctionDealServiceClient.audience_segment_path(**expected) + + # Check that the path construction is reversible. + actual = PrivateAuctionDealServiceClient.parse_audience_segment_path(path) + assert expected == actual + + +def test_bandwidth_group_path(): + network_code = "squid" + bandwidth_group = "clam" expected = "networks/{network_code}/bandwidthGroups/{bandwidth_group}".format( network_code=network_code, bandwidth_group=bandwidth_group, @@ -3331,8 +3607,8 @@ def test_bandwidth_group_path(): def test_parse_bandwidth_group_path(): expected = { - "network_code": "cuttlefish", - "bandwidth_group": "mussel", + "network_code": "whelk", + "bandwidth_group": "octopus", } path = PrivateAuctionDealServiceClient.bandwidth_group_path(**expected) @@ -3341,9 +3617,130 @@ def test_parse_bandwidth_group_path(): assert expected == actual -def test_custom_targeting_key_path(): +def test_browser_path(): + network_code = "oyster" + browser = "nudibranch" + expected = "networks/{network_code}/browsers/{browser}".format( + network_code=network_code, + browser=browser, + ) + actual = PrivateAuctionDealServiceClient.browser_path(network_code, browser) + assert expected == actual + + +def test_parse_browser_path(): + expected = { + "network_code": "cuttlefish", + "browser": "mussel", + } + path = PrivateAuctionDealServiceClient.browser_path(**expected) + + # Check that the path construction is reversible. + actual = PrivateAuctionDealServiceClient.parse_browser_path(path) + assert expected == actual + + +def test_browser_language_path(): network_code = "winkle" - custom_targeting_key = "nautilus" + browser_language = "nautilus" + expected = "networks/{network_code}/browserLanguages/{browser_language}".format( + network_code=network_code, + browser_language=browser_language, + ) + actual = PrivateAuctionDealServiceClient.browser_language_path( + network_code, browser_language + ) + assert expected == actual + + +def test_parse_browser_language_path(): + expected = { + "network_code": "scallop", + "browser_language": "abalone", + } + path = PrivateAuctionDealServiceClient.browser_language_path(**expected) + + # Check that the path construction is reversible. + actual = PrivateAuctionDealServiceClient.parse_browser_language_path(path) + assert expected == actual + + +def test_cms_metadata_value_path(): + network_code = "squid" + cms_metadata_value = "clam" + expected = "networks/{network_code}/cmsMetadataValues/{cms_metadata_value}".format( + network_code=network_code, + cms_metadata_value=cms_metadata_value, + ) + actual = PrivateAuctionDealServiceClient.cms_metadata_value_path( + network_code, cms_metadata_value + ) + assert expected == actual + + +def test_parse_cms_metadata_value_path(): + expected = { + "network_code": "whelk", + "cms_metadata_value": "octopus", + } + path = PrivateAuctionDealServiceClient.cms_metadata_value_path(**expected) + + # Check that the path construction is reversible. + actual = PrivateAuctionDealServiceClient.parse_cms_metadata_value_path(path) + assert expected == actual + + +def test_content_path(): + network_code = "oyster" + content = "nudibranch" + expected = "networks/{network_code}/content/{content}".format( + network_code=network_code, + content=content, + ) + actual = PrivateAuctionDealServiceClient.content_path(network_code, content) + assert expected == actual + + +def test_parse_content_path(): + expected = { + "network_code": "cuttlefish", + "content": "mussel", + } + path = PrivateAuctionDealServiceClient.content_path(**expected) + + # Check that the path construction is reversible. + actual = PrivateAuctionDealServiceClient.parse_content_path(path) + assert expected == actual + + +def test_content_bundle_path(): + network_code = "winkle" + content_bundle = "nautilus" + expected = "networks/{network_code}/contentBundles/{content_bundle}".format( + network_code=network_code, + content_bundle=content_bundle, + ) + actual = PrivateAuctionDealServiceClient.content_bundle_path( + network_code, content_bundle + ) + assert expected == actual + + +def test_parse_content_bundle_path(): + expected = { + "network_code": "scallop", + "content_bundle": "abalone", + } + path = PrivateAuctionDealServiceClient.content_bundle_path(**expected) + + # Check that the path construction is reversible. + actual = PrivateAuctionDealServiceClient.parse_content_bundle_path(path) + assert expected == actual + + +def test_custom_targeting_key_path(): + network_code = "squid" + custom_targeting_key = "clam" expected = ( "networks/{network_code}/customTargetingKeys/{custom_targeting_key}".format( network_code=network_code, @@ -3358,8 +3755,8 @@ def test_custom_targeting_key_path(): def test_parse_custom_targeting_key_path(): expected = { - "network_code": "scallop", - "custom_targeting_key": "abalone", + "network_code": "whelk", + "custom_targeting_key": "octopus", } path = PrivateAuctionDealServiceClient.custom_targeting_key_path(**expected) @@ -3369,8 +3766,8 @@ def test_parse_custom_targeting_key_path(): def test_custom_targeting_value_path(): - network_code = "squid" - custom_targeting_value = "clam" + network_code = "oyster" + custom_targeting_value = "nudibranch" expected = ( "networks/{network_code}/customTargetingValues/{custom_targeting_value}".format( network_code=network_code, @@ -3385,8 +3782,8 @@ def test_custom_targeting_value_path(): def test_parse_custom_targeting_value_path(): expected = { - "network_code": "whelk", - "custom_targeting_value": "octopus", + "network_code": "cuttlefish", + "custom_targeting_value": "mussel", } path = PrivateAuctionDealServiceClient.custom_targeting_value_path(**expected) @@ -3395,9 +3792,34 @@ def test_parse_custom_targeting_value_path(): assert expected == actual +def test_device_capability_path(): + network_code = "winkle" + device_capability = "nautilus" + expected = "networks/{network_code}/deviceCapabilities/{device_capability}".format( + network_code=network_code, + device_capability=device_capability, + ) + actual = PrivateAuctionDealServiceClient.device_capability_path( + network_code, device_capability + ) + assert expected == actual + + +def test_parse_device_capability_path(): + expected = { + "network_code": "scallop", + "device_capability": "abalone", + } + path = PrivateAuctionDealServiceClient.device_capability_path(**expected) + + # Check that the path construction is reversible. + actual = PrivateAuctionDealServiceClient.parse_device_capability_path(path) + assert expected == actual + + def test_device_category_path(): - network_code = "oyster" - device_category = "nudibranch" + network_code = "squid" + device_category = "clam" expected = "networks/{network_code}/deviceCategories/{device_category}".format( network_code=network_code, device_category=device_category, @@ -3410,8 +3832,8 @@ def test_device_category_path(): def test_parse_device_category_path(): expected = { - "network_code": "cuttlefish", - "device_category": "mussel", + "network_code": "whelk", + "device_category": "octopus", } path = PrivateAuctionDealServiceClient.device_category_path(**expected) @@ -3420,6 +3842,33 @@ def test_parse_device_category_path(): assert expected == actual +def test_device_manufacturer_path(): + network_code = "oyster" + device_manufacturer = "nudibranch" + expected = ( + "networks/{network_code}/deviceManufacturers/{device_manufacturer}".format( + network_code=network_code, + device_manufacturer=device_manufacturer, + ) + ) + actual = PrivateAuctionDealServiceClient.device_manufacturer_path( + network_code, device_manufacturer + ) + assert expected == actual + + +def test_parse_device_manufacturer_path(): + expected = { + "network_code": "cuttlefish", + "device_manufacturer": "mussel", + } + path = PrivateAuctionDealServiceClient.device_manufacturer_path(**expected) + + # Check that the path construction is reversible. + actual = PrivateAuctionDealServiceClient.parse_device_manufacturer_path(path) + assert expected == actual + + def test_geo_target_path(): network_code = "winkle" geo_target = "nautilus" @@ -3443,6 +3892,83 @@ def test_parse_geo_target_path(): assert expected == actual +def test_mobile_carrier_path(): + network_code = "squid" + mobile_carrier = "clam" + expected = "networks/{network_code}/mobileCarriers/{mobile_carrier}".format( + network_code=network_code, + mobile_carrier=mobile_carrier, + ) + actual = PrivateAuctionDealServiceClient.mobile_carrier_path( + network_code, mobile_carrier + ) + assert expected == actual + + +def test_parse_mobile_carrier_path(): + expected = { + "network_code": "whelk", + "mobile_carrier": "octopus", + } + path = PrivateAuctionDealServiceClient.mobile_carrier_path(**expected) + + # Check that the path construction is reversible. + actual = PrivateAuctionDealServiceClient.parse_mobile_carrier_path(path) + assert expected == actual + + +def test_mobile_device_path(): + network_code = "oyster" + mobile_device = "nudibranch" + expected = "networks/{network_code}/mobileDevices/{mobile_device}".format( + network_code=network_code, + mobile_device=mobile_device, + ) + actual = PrivateAuctionDealServiceClient.mobile_device_path( + network_code, mobile_device + ) + assert expected == actual + + +def test_parse_mobile_device_path(): + expected = { + "network_code": "cuttlefish", + "mobile_device": "mussel", + } + path = PrivateAuctionDealServiceClient.mobile_device_path(**expected) + + # Check that the path construction is reversible. + actual = PrivateAuctionDealServiceClient.parse_mobile_device_path(path) + assert expected == actual + + +def test_mobile_device_submodel_path(): + network_code = "winkle" + mobile_device_submodel = "nautilus" + expected = ( + "networks/{network_code}/mobileDeviceSubmodels/{mobile_device_submodel}".format( + network_code=network_code, + mobile_device_submodel=mobile_device_submodel, + ) + ) + actual = PrivateAuctionDealServiceClient.mobile_device_submodel_path( + network_code, mobile_device_submodel + ) + assert expected == actual + + +def test_parse_mobile_device_submodel_path(): + expected = { + "network_code": "scallop", + "mobile_device_submodel": "abalone", + } + path = PrivateAuctionDealServiceClient.mobile_device_submodel_path(**expected) + + # Check that the path construction is reversible. + actual = PrivateAuctionDealServiceClient.parse_mobile_device_submodel_path(path) + assert expected == actual + + def test_network_path(): network_code = "squid" expected = "networks/{network_code}".format( diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_report_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_report_service.py index baf3b30d1779..ba6e3b6e7f4d 100644 --- a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_report_service.py +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_report_service.py @@ -72,7 +72,12 @@ pagers, transports, ) -from google.ads.admanager_v1.types import report_messages, report_service +from google.ads.admanager_v1.types import ( + report_definition, + report_messages, + report_service, + report_value, +) CRED_INFO_JSON = { "credential_source": "/path/to/file", @@ -2048,9 +2053,9 @@ def test_fetch_report_result_rows_rest_pager(transport: str = "rest"): response = ( report_service.FetchReportResultRowsResponse( rows=[ - report_messages.Report.DataTable.Row(), - report_messages.Report.DataTable.Row(), - report_messages.Report.DataTable.Row(), + report_messages.ReportDataTable.Row(), + report_messages.ReportDataTable.Row(), + report_messages.ReportDataTable.Row(), ], next_page_token="abc", ), @@ -2060,14 +2065,14 @@ def test_fetch_report_result_rows_rest_pager(transport: str = "rest"): ), report_service.FetchReportResultRowsResponse( rows=[ - report_messages.Report.DataTable.Row(), + report_messages.ReportDataTable.Row(), ], next_page_token="ghi", ), report_service.FetchReportResultRowsResponse( rows=[ - report_messages.Report.DataTable.Row(), - report_messages.Report.DataTable.Row(), + report_messages.ReportDataTable.Row(), + report_messages.ReportDataTable.Row(), ], ), ) @@ -2090,7 +2095,7 @@ def test_fetch_report_result_rows_rest_pager(transport: str = "rest"): results = list(pager) assert len(results) == 6 - assert all(isinstance(i, report_messages.Report.DataTable.Row) for i in results) + assert all(isinstance(i, report_messages.ReportDataTable.Row) for i in results) pages = list(client.fetch_report_result_rows(request=sample_request).pages) for page_, token in zip(pages, ["abc", "def", "ghi", ""]): @@ -2485,12 +2490,12 @@ def test_create_report_rest_call_success(request_type): "report_id": 968, "visibility": 1, "report_definition": { - "dimensions": [242], - "metrics": [61], + "dimensions": [575], + "metrics": [223], "filters": [ { "field_filter": { - "field": {"dimension": 242, "metric": 61}, + "field": {"dimension": 575, "metric": 223}, "operation": 1, "values": [ { @@ -2502,10 +2507,11 @@ def test_create_report_rest_call_success(request_type): "string_list_value": { "values": ["values_value1", "values_value2"] }, + "double_list_value": {"values": [0.657, 0.658]}, "bytes_value": b"bytes_value_blob", } ], - "slice_": {"dimension": 242, "value": {}}, + "slice_": {"dimension": 575, "value": {}}, "time_period_index": 1800, "metric_value_type": 1, }, @@ -2771,12 +2777,12 @@ def test_update_report_rest_call_success(request_type): "report_id": 968, "visibility": 1, "report_definition": { - "dimensions": [242], - "metrics": [61], + "dimensions": [575], + "metrics": [223], "filters": [ { "field_filter": { - "field": {"dimension": 242, "metric": 61}, + "field": {"dimension": 575, "metric": 223}, "operation": 1, "values": [ { @@ -2788,10 +2794,11 @@ def test_update_report_rest_call_success(request_type): "string_list_value": { "values": ["values_value1", "values_value2"] }, + "double_list_value": {"values": [0.657, 0.658]}, "bytes_value": b"bytes_value_blob", } ], - "slice_": {"dimension": 242, "value": {}}, + "slice_": {"dimension": 575, "value": {}}, "time_period_index": 1800, "metric_value_type": 1, }, diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_site_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_site_service.py new file mode 100644 index 000000000000..27983ddafd4b --- /dev/null +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_site_service.py @@ -0,0 +1,4442 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + +from google.ads.admanager_v1.services.site_service import ( + SiteServiceClient, + pagers, + transports, +) +from google.ads.admanager_v1.types import site_enums, site_messages, site_service + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert SiteServiceClient._get_default_mtls_endpoint(None) is None + assert ( + SiteServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + ) + assert ( + SiteServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + SiteServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + SiteServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert SiteServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +def test__read_environment_variables(): + assert SiteServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert SiteServiceClient._read_environment_variables() == (True, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert SiteServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + SiteServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert SiteServiceClient._read_environment_variables() == (False, "never", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert SiteServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert SiteServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + SiteServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert SiteServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert SiteServiceClient._get_client_cert_source(None, False) is None + assert ( + SiteServiceClient._get_client_cert_source(mock_provided_cert_source, False) + is None + ) + assert ( + SiteServiceClient._get_client_cert_source(mock_provided_cert_source, True) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + SiteServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + SiteServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + SiteServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(SiteServiceClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = SiteServiceClient._DEFAULT_UNIVERSE + default_endpoint = SiteServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = SiteServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + SiteServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + SiteServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == SiteServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + SiteServiceClient._get_api_endpoint(None, None, default_universe, "auto") + == default_endpoint + ) + assert ( + SiteServiceClient._get_api_endpoint(None, None, default_universe, "always") + == SiteServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + SiteServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == SiteServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + SiteServiceClient._get_api_endpoint(None, None, mock_universe, "never") + == mock_endpoint + ) + assert ( + SiteServiceClient._get_api_endpoint(None, None, default_universe, "never") + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + SiteServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + SiteServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + SiteServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + SiteServiceClient._get_universe_domain(None, None) + == SiteServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + SiteServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SiteServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SiteServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (SiteServiceClient, "rest"), + ], +) +def test_site_service_client_from_service_account_info(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.SiteServiceRestTransport, "rest"), + ], +) +def test_site_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (SiteServiceClient, "rest"), + ], +) +def test_site_service_client_from_service_account_file(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +def test_site_service_client_get_transport_class(): + transport = SiteServiceClient.get_transport_class() + available_transports = [ + transports.SiteServiceRestTransport, + ] + assert transport in available_transports + + transport = SiteServiceClient.get_transport_class("rest") + assert transport == transports.SiteServiceRestTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (SiteServiceClient, transports.SiteServiceRestTransport, "rest"), + ], +) +@mock.patch.object( + SiteServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(SiteServiceClient), +) +def test_site_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(SiteServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(SiteServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + (SiteServiceClient, transports.SiteServiceRestTransport, "rest", "true"), + (SiteServiceClient, transports.SiteServiceRestTransport, "rest", "false"), + ], +) +@mock.patch.object( + SiteServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(SiteServiceClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_site_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [SiteServiceClient]) +@mock.patch.object( + SiteServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SiteServiceClient) +) +def test_site_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize("client_class", [SiteServiceClient]) +@mock.patch.object( + SiteServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(SiteServiceClient), +) +def test_site_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = SiteServiceClient._DEFAULT_UNIVERSE + default_endpoint = SiteServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = SiteServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (SiteServiceClient, transports.SiteServiceRestTransport, "rest"), + ], +) +def test_site_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + (SiteServiceClient, transports.SiteServiceRestTransport, "rest", None), + ], +) +def test_site_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_get_site_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_site in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_site] = mock_rpc + + request = {} + client.get_site(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_site(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_site_rest_required_fields(request_type=site_service.GetSiteRequest): + transport_class = transports.SiteServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_site._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_site._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = site_messages.Site() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = site_messages.Site.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_site(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_site_rest_unset_required_fields(): + transport = transports.SiteServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_site._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_site_rest_flattened(): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = site_messages.Site() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "networks/sample1/sites/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = site_messages.Site.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_site(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=networks/*/sites/*}" % client.transport._host, args[1] + ) + + +def test_get_site_rest_flattened_error(transport: str = "rest"): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_site( + site_service.GetSiteRequest(), + name="name_value", + ) + + +def test_list_sites_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_sites in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_sites] = mock_rpc + + request = {} + client.list_sites(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_sites(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_sites_rest_required_fields(request_type=site_service.ListSitesRequest): + transport_class = transports.SiteServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_sites._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_sites._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + "skip", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = site_service.ListSitesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = site_service.ListSitesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_sites(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_sites_rest_unset_required_fields(): + transport = transports.SiteServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_sites._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + "skip", + ) + ) + & set(("parent",)) + ) + + +def test_list_sites_rest_flattened(): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = site_service.ListSitesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = site_service.ListSitesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_sites(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/sites" % client.transport._host, args[1] + ) + + +def test_list_sites_rest_flattened_error(transport: str = "rest"): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_sites( + site_service.ListSitesRequest(), + parent="parent_value", + ) + + +def test_list_sites_rest_pager(transport: str = "rest"): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + site_service.ListSitesResponse( + sites=[ + site_messages.Site(), + site_messages.Site(), + site_messages.Site(), + ], + next_page_token="abc", + ), + site_service.ListSitesResponse( + sites=[], + next_page_token="def", + ), + site_service.ListSitesResponse( + sites=[ + site_messages.Site(), + ], + next_page_token="ghi", + ), + site_service.ListSitesResponse( + sites=[ + site_messages.Site(), + site_messages.Site(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(site_service.ListSitesResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "networks/sample1"} + + pager = client.list_sites(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, site_messages.Site) for i in results) + + pages = list(client.list_sites(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_create_site_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.create_site in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.create_site] = mock_rpc + + request = {} + client.create_site(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.create_site(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_site_rest_required_fields(request_type=site_service.CreateSiteRequest): + transport_class = transports.SiteServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_site._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_site._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = site_messages.Site() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = site_messages.Site.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.create_site(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_create_site_rest_unset_required_fields(): + transport = transports.SiteServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_site._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "site", + ) + ) + ) + + +def test_create_site_rest_flattened(): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = site_messages.Site() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + site=site_messages.Site(name="name_value"), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = site_messages.Site.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.create_site(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/sites" % client.transport._host, args[1] + ) + + +def test_create_site_rest_flattened_error(transport: str = "rest"): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_site( + site_service.CreateSiteRequest(), + parent="parent_value", + site=site_messages.Site(name="name_value"), + ) + + +def test_batch_create_sites_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_create_sites in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_create_sites + ] = mock_rpc + + request = {} + client.batch_create_sites(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_create_sites(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_create_sites_rest_required_fields( + request_type=site_service.BatchCreateSitesRequest, +): + transport_class = transports.SiteServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_create_sites._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_create_sites._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = site_service.BatchCreateSitesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = site_service.BatchCreateSitesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_create_sites(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_create_sites_rest_unset_required_fields(): + transport = transports.SiteServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_create_sites._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "requests", + ) + ) + ) + + +def test_batch_create_sites_rest_flattened(): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = site_service.BatchCreateSitesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + requests=[site_service.CreateSiteRequest(parent="parent_value")], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = site_service.BatchCreateSitesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.batch_create_sites(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/sites:batchCreate" % client.transport._host, + args[1], + ) + + +def test_batch_create_sites_rest_flattened_error(transport: str = "rest"): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_create_sites( + site_service.BatchCreateSitesRequest(), + parent="parent_value", + requests=[site_service.CreateSiteRequest(parent="parent_value")], + ) + + +def test_update_site_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.update_site in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.update_site] = mock_rpc + + request = {} + client.update_site(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_site(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_update_site_rest_required_fields(request_type=site_service.UpdateSiteRequest): + transport_class = transports.SiteServiceRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_site._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_site._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = site_messages.Site() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = site_messages.Site.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.update_site(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_site_rest_unset_required_fields(): + transport = transports.SiteServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_site._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("updateMask",)) + & set( + ( + "site", + "updateMask", + ) + ) + ) + + +def test_update_site_rest_flattened(): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = site_messages.Site() + + # get arguments that satisfy an http rule for this method + sample_request = {"site": {"name": "networks/sample1/sites/sample2"}} + + # get truthy value for each flattened field + mock_args = dict( + site=site_messages.Site(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = site_messages.Site.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.update_site(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{site.name=networks/*/sites/*}" % client.transport._host, args[1] + ) + + +def test_update_site_rest_flattened_error(transport: str = "rest"): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_site( + site_service.UpdateSiteRequest(), + site=site_messages.Site(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_batch_update_sites_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_update_sites in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_update_sites + ] = mock_rpc + + request = {} + client.batch_update_sites(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_update_sites(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_update_sites_rest_required_fields( + request_type=site_service.BatchUpdateSitesRequest, +): + transport_class = transports.SiteServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_update_sites._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_update_sites._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = site_service.BatchUpdateSitesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = site_service.BatchUpdateSitesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_update_sites(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_update_sites_rest_unset_required_fields(): + transport = transports.SiteServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_update_sites._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "requests", + ) + ) + ) + + +def test_batch_update_sites_rest_flattened(): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = site_service.BatchUpdateSitesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + requests=[ + site_service.UpdateSiteRequest( + site=site_messages.Site(name="name_value") + ) + ], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = site_service.BatchUpdateSitesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.batch_update_sites(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/sites:batchUpdate" % client.transport._host, + args[1], + ) + + +def test_batch_update_sites_rest_flattened_error(transport: str = "rest"): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_update_sites( + site_service.BatchUpdateSitesRequest(), + parent="parent_value", + requests=[ + site_service.UpdateSiteRequest( + site=site_messages.Site(name="name_value") + ) + ], + ) + + +def test_batch_deactivate_sites_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_deactivate_sites + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_deactivate_sites + ] = mock_rpc + + request = {} + client.batch_deactivate_sites(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_deactivate_sites(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_deactivate_sites_rest_required_fields( + request_type=site_service.BatchDeactivateSitesRequest, +): + transport_class = transports.SiteServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["names"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_deactivate_sites._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + jsonified_request["names"] = "names_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_deactivate_sites._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "names" in jsonified_request + assert jsonified_request["names"] == "names_value" + + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = site_service.BatchDeactivateSitesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = site_service.BatchDeactivateSitesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_deactivate_sites(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_deactivate_sites_rest_unset_required_fields(): + transport = transports.SiteServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_deactivate_sites._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "names", + ) + ) + ) + + +def test_batch_deactivate_sites_rest_flattened(): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = site_service.BatchDeactivateSitesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + names=["names_value"], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = site_service.BatchDeactivateSitesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.batch_deactivate_sites(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/sites:batchDeactivate" % client.transport._host, + args[1], + ) + + +def test_batch_deactivate_sites_rest_flattened_error(transport: str = "rest"): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_deactivate_sites( + site_service.BatchDeactivateSitesRequest(), + parent="parent_value", + names=["names_value"], + ) + + +def test_batch_submit_sites_for_approval_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_submit_sites_for_approval + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_submit_sites_for_approval + ] = mock_rpc + + request = {} + client.batch_submit_sites_for_approval(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_submit_sites_for_approval(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_submit_sites_for_approval_rest_required_fields( + request_type=site_service.BatchSubmitSitesForApprovalRequest, +): + transport_class = transports.SiteServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["names"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_submit_sites_for_approval._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + jsonified_request["names"] = "names_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_submit_sites_for_approval._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "names" in jsonified_request + assert jsonified_request["names"] == "names_value" + + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = site_service.BatchSubmitSitesForApprovalResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = site_service.BatchSubmitSitesForApprovalResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_submit_sites_for_approval(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_submit_sites_for_approval_rest_unset_required_fields(): + transport = transports.SiteServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_submit_sites_for_approval._get_unset_required_fields( + {} + ) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "names", + ) + ) + ) + + +def test_batch_submit_sites_for_approval_rest_flattened(): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = site_service.BatchSubmitSitesForApprovalResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + names=["names_value"], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = site_service.BatchSubmitSitesForApprovalResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.batch_submit_sites_for_approval(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/sites:batchSubmitForApproval" + % client.transport._host, + args[1], + ) + + +def test_batch_submit_sites_for_approval_rest_flattened_error(transport: str = "rest"): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_submit_sites_for_approval( + site_service.BatchSubmitSitesForApprovalRequest(), + parent="parent_value", + names=["names_value"], + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.SiteServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.SiteServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SiteServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.SiteServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = SiteServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = SiteServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.SiteServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SiteServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.SiteServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = SiteServiceClient(transport=transport) + assert client.transport is transport + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.SiteServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_rest(): + transport = SiteServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_site_rest_bad_request(request_type=site_service.GetSiteRequest): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/sites/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_site(request) + + +@pytest.mark.parametrize( + "request_type", + [ + site_service.GetSiteRequest, + dict, + ], +) +def test_get_site_rest_call_success(request_type): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/sites/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = site_messages.Site( + name="name_value", + url="url_value", + child_network_code="child_network_code_value", + approval_status=site_enums.SiteApprovalStatusEnum.SiteApprovalStatus.APPROVED, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = site_messages.Site.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_site(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, site_messages.Site) + assert response.name == "name_value" + assert response.url == "url_value" + assert response.child_network_code == "child_network_code_value" + assert ( + response.approval_status + == site_enums.SiteApprovalStatusEnum.SiteApprovalStatus.APPROVED + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_site_rest_interceptors(null_interceptor): + transport = transports.SiteServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SiteServiceRestInterceptor(), + ) + client = SiteServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SiteServiceRestInterceptor, "post_get_site" + ) as post, mock.patch.object( + transports.SiteServiceRestInterceptor, "post_get_site_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.SiteServiceRestInterceptor, "pre_get_site" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = site_service.GetSiteRequest.pb(site_service.GetSiteRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = site_messages.Site.to_json(site_messages.Site()) + req.return_value.content = return_value + + request = site_service.GetSiteRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = site_messages.Site() + post_with_metadata.return_value = site_messages.Site(), metadata + + client.get_site( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_sites_rest_bad_request(request_type=site_service.ListSitesRequest): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_sites(request) + + +@pytest.mark.parametrize( + "request_type", + [ + site_service.ListSitesRequest, + dict, + ], +) +def test_list_sites_rest_call_success(request_type): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = site_service.ListSitesResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = site_service.ListSitesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_sites(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListSitesPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_sites_rest_interceptors(null_interceptor): + transport = transports.SiteServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SiteServiceRestInterceptor(), + ) + client = SiteServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SiteServiceRestInterceptor, "post_list_sites" + ) as post, mock.patch.object( + transports.SiteServiceRestInterceptor, "post_list_sites_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.SiteServiceRestInterceptor, "pre_list_sites" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = site_service.ListSitesRequest.pb(site_service.ListSitesRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = site_service.ListSitesResponse.to_json( + site_service.ListSitesResponse() + ) + req.return_value.content = return_value + + request = site_service.ListSitesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = site_service.ListSitesResponse() + post_with_metadata.return_value = site_service.ListSitesResponse(), metadata + + client.list_sites( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_create_site_rest_bad_request(request_type=site_service.CreateSiteRequest): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.create_site(request) + + +@pytest.mark.parametrize( + "request_type", + [ + site_service.CreateSiteRequest, + dict, + ], +) +def test_create_site_rest_call_success(request_type): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request_init["site"] = { + "name": "name_value", + "url": "url_value", + "child_network_code": "child_network_code_value", + "approval_status": 1, + "approval_status_update_time": {"seconds": 751, "nanos": 543}, + "disapproval_reasons": [{"type_": 1, "details": "details_value"}], + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = site_service.CreateSiteRequest.meta.fields["site"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["site"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["site"][field])): + del request_init["site"][field][i][subfield] + else: + del request_init["site"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = site_messages.Site( + name="name_value", + url="url_value", + child_network_code="child_network_code_value", + approval_status=site_enums.SiteApprovalStatusEnum.SiteApprovalStatus.APPROVED, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = site_messages.Site.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.create_site(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, site_messages.Site) + assert response.name == "name_value" + assert response.url == "url_value" + assert response.child_network_code == "child_network_code_value" + assert ( + response.approval_status + == site_enums.SiteApprovalStatusEnum.SiteApprovalStatus.APPROVED + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_site_rest_interceptors(null_interceptor): + transport = transports.SiteServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SiteServiceRestInterceptor(), + ) + client = SiteServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SiteServiceRestInterceptor, "post_create_site" + ) as post, mock.patch.object( + transports.SiteServiceRestInterceptor, "post_create_site_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.SiteServiceRestInterceptor, "pre_create_site" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = site_service.CreateSiteRequest.pb(site_service.CreateSiteRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = site_messages.Site.to_json(site_messages.Site()) + req.return_value.content = return_value + + request = site_service.CreateSiteRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = site_messages.Site() + post_with_metadata.return_value = site_messages.Site(), metadata + + client.create_site( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_batch_create_sites_rest_bad_request( + request_type=site_service.BatchCreateSitesRequest, +): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.batch_create_sites(request) + + +@pytest.mark.parametrize( + "request_type", + [ + site_service.BatchCreateSitesRequest, + dict, + ], +) +def test_batch_create_sites_rest_call_success(request_type): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = site_service.BatchCreateSitesResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = site_service.BatchCreateSitesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.batch_create_sites(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, site_service.BatchCreateSitesResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_create_sites_rest_interceptors(null_interceptor): + transport = transports.SiteServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SiteServiceRestInterceptor(), + ) + client = SiteServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SiteServiceRestInterceptor, "post_batch_create_sites" + ) as post, mock.patch.object( + transports.SiteServiceRestInterceptor, "post_batch_create_sites_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.SiteServiceRestInterceptor, "pre_batch_create_sites" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = site_service.BatchCreateSitesRequest.pb( + site_service.BatchCreateSitesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = site_service.BatchCreateSitesResponse.to_json( + site_service.BatchCreateSitesResponse() + ) + req.return_value.content = return_value + + request = site_service.BatchCreateSitesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = site_service.BatchCreateSitesResponse() + post_with_metadata.return_value = ( + site_service.BatchCreateSitesResponse(), + metadata, + ) + + client.batch_create_sites( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_update_site_rest_bad_request(request_type=site_service.UpdateSiteRequest): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"site": {"name": "networks/sample1/sites/sample2"}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.update_site(request) + + +@pytest.mark.parametrize( + "request_type", + [ + site_service.UpdateSiteRequest, + dict, + ], +) +def test_update_site_rest_call_success(request_type): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"site": {"name": "networks/sample1/sites/sample2"}} + request_init["site"] = { + "name": "networks/sample1/sites/sample2", + "url": "url_value", + "child_network_code": "child_network_code_value", + "approval_status": 1, + "approval_status_update_time": {"seconds": 751, "nanos": 543}, + "disapproval_reasons": [{"type_": 1, "details": "details_value"}], + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = site_service.UpdateSiteRequest.meta.fields["site"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["site"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["site"][field])): + del request_init["site"][field][i][subfield] + else: + del request_init["site"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = site_messages.Site( + name="name_value", + url="url_value", + child_network_code="child_network_code_value", + approval_status=site_enums.SiteApprovalStatusEnum.SiteApprovalStatus.APPROVED, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = site_messages.Site.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.update_site(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, site_messages.Site) + assert response.name == "name_value" + assert response.url == "url_value" + assert response.child_network_code == "child_network_code_value" + assert ( + response.approval_status + == site_enums.SiteApprovalStatusEnum.SiteApprovalStatus.APPROVED + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_site_rest_interceptors(null_interceptor): + transport = transports.SiteServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SiteServiceRestInterceptor(), + ) + client = SiteServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SiteServiceRestInterceptor, "post_update_site" + ) as post, mock.patch.object( + transports.SiteServiceRestInterceptor, "post_update_site_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.SiteServiceRestInterceptor, "pre_update_site" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = site_service.UpdateSiteRequest.pb(site_service.UpdateSiteRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = site_messages.Site.to_json(site_messages.Site()) + req.return_value.content = return_value + + request = site_service.UpdateSiteRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = site_messages.Site() + post_with_metadata.return_value = site_messages.Site(), metadata + + client.update_site( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_batch_update_sites_rest_bad_request( + request_type=site_service.BatchUpdateSitesRequest, +): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.batch_update_sites(request) + + +@pytest.mark.parametrize( + "request_type", + [ + site_service.BatchUpdateSitesRequest, + dict, + ], +) +def test_batch_update_sites_rest_call_success(request_type): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = site_service.BatchUpdateSitesResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = site_service.BatchUpdateSitesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.batch_update_sites(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, site_service.BatchUpdateSitesResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_update_sites_rest_interceptors(null_interceptor): + transport = transports.SiteServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SiteServiceRestInterceptor(), + ) + client = SiteServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SiteServiceRestInterceptor, "post_batch_update_sites" + ) as post, mock.patch.object( + transports.SiteServiceRestInterceptor, "post_batch_update_sites_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.SiteServiceRestInterceptor, "pre_batch_update_sites" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = site_service.BatchUpdateSitesRequest.pb( + site_service.BatchUpdateSitesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = site_service.BatchUpdateSitesResponse.to_json( + site_service.BatchUpdateSitesResponse() + ) + req.return_value.content = return_value + + request = site_service.BatchUpdateSitesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = site_service.BatchUpdateSitesResponse() + post_with_metadata.return_value = ( + site_service.BatchUpdateSitesResponse(), + metadata, + ) + + client.batch_update_sites( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_batch_deactivate_sites_rest_bad_request( + request_type=site_service.BatchDeactivateSitesRequest, +): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.batch_deactivate_sites(request) + + +@pytest.mark.parametrize( + "request_type", + [ + site_service.BatchDeactivateSitesRequest, + dict, + ], +) +def test_batch_deactivate_sites_rest_call_success(request_type): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = site_service.BatchDeactivateSitesResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = site_service.BatchDeactivateSitesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.batch_deactivate_sites(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, site_service.BatchDeactivateSitesResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_deactivate_sites_rest_interceptors(null_interceptor): + transport = transports.SiteServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SiteServiceRestInterceptor(), + ) + client = SiteServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SiteServiceRestInterceptor, "post_batch_deactivate_sites" + ) as post, mock.patch.object( + transports.SiteServiceRestInterceptor, + "post_batch_deactivate_sites_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.SiteServiceRestInterceptor, "pre_batch_deactivate_sites" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = site_service.BatchDeactivateSitesRequest.pb( + site_service.BatchDeactivateSitesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = site_service.BatchDeactivateSitesResponse.to_json( + site_service.BatchDeactivateSitesResponse() + ) + req.return_value.content = return_value + + request = site_service.BatchDeactivateSitesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = site_service.BatchDeactivateSitesResponse() + post_with_metadata.return_value = ( + site_service.BatchDeactivateSitesResponse(), + metadata, + ) + + client.batch_deactivate_sites( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_batch_submit_sites_for_approval_rest_bad_request( + request_type=site_service.BatchSubmitSitesForApprovalRequest, +): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.batch_submit_sites_for_approval(request) + + +@pytest.mark.parametrize( + "request_type", + [ + site_service.BatchSubmitSitesForApprovalRequest, + dict, + ], +) +def test_batch_submit_sites_for_approval_rest_call_success(request_type): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = site_service.BatchSubmitSitesForApprovalResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = site_service.BatchSubmitSitesForApprovalResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.batch_submit_sites_for_approval(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, site_service.BatchSubmitSitesForApprovalResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_submit_sites_for_approval_rest_interceptors(null_interceptor): + transport = transports.SiteServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.SiteServiceRestInterceptor(), + ) + client = SiteServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.SiteServiceRestInterceptor, "post_batch_submit_sites_for_approval" + ) as post, mock.patch.object( + transports.SiteServiceRestInterceptor, + "post_batch_submit_sites_for_approval_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.SiteServiceRestInterceptor, "pre_batch_submit_sites_for_approval" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = site_service.BatchSubmitSitesForApprovalRequest.pb( + site_service.BatchSubmitSitesForApprovalRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = site_service.BatchSubmitSitesForApprovalResponse.to_json( + site_service.BatchSubmitSitesForApprovalResponse() + ) + req.return_value.content = return_value + + request = site_service.BatchSubmitSitesForApprovalRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = site_service.BatchSubmitSitesForApprovalResponse() + post_with_metadata.return_value = ( + site_service.BatchSubmitSitesForApprovalResponse(), + metadata, + ) + + client.batch_submit_sites_for_approval( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "networks/sample1/operations/reports/runs/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "networks/sample1/operations/reports/runs/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_initialize_client_w_rest(): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_site_empty_call_rest(): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_site), "__call__") as call: + client.get_site(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = site_service.GetSiteRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_sites_empty_call_rest(): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_sites), "__call__") as call: + client.list_sites(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = site_service.ListSitesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_site_empty_call_rest(): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_site), "__call__") as call: + client.create_site(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = site_service.CreateSiteRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_create_sites_empty_call_rest(): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_sites), "__call__" + ) as call: + client.batch_create_sites(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = site_service.BatchCreateSitesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_site_empty_call_rest(): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_site), "__call__") as call: + client.update_site(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = site_service.UpdateSiteRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_update_sites_empty_call_rest(): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_update_sites), "__call__" + ) as call: + client.batch_update_sites(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = site_service.BatchUpdateSitesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_deactivate_sites_empty_call_rest(): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_deactivate_sites), "__call__" + ) as call: + client.batch_deactivate_sites(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = site_service.BatchDeactivateSitesRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_submit_sites_for_approval_empty_call_rest(): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_submit_sites_for_approval), "__call__" + ) as call: + client.batch_submit_sites_for_approval(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = site_service.BatchSubmitSitesForApprovalRequest() + + assert args[0] == request_msg + + +def test_site_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.SiteServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_site_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.ads.admanager_v1.services.site_service.transports.SiteServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.SiteServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "get_site", + "list_sites", + "create_site", + "batch_create_sites", + "update_site", + "batch_update_sites", + "batch_deactivate_sites", + "batch_submit_sites_for_approval", + "get_operation", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_site_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.ads.admanager_v1.services.site_service.transports.SiteServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.SiteServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id="octopus", + ) + + +def test_site_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.ads.admanager_v1.services.site_service.transports.SiteServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.SiteServiceTransport() + adc.assert_called_once() + + +def test_site_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + SiteServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id=None, + ) + + +def test_site_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.SiteServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_site_service_host_no_port(transport_name): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_site_service_host_with_port(transport_name): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_site_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = SiteServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = SiteServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.get_site._session + session2 = client2.transport.get_site._session + assert session1 != session2 + session1 = client1.transport.list_sites._session + session2 = client2.transport.list_sites._session + assert session1 != session2 + session1 = client1.transport.create_site._session + session2 = client2.transport.create_site._session + assert session1 != session2 + session1 = client1.transport.batch_create_sites._session + session2 = client2.transport.batch_create_sites._session + assert session1 != session2 + session1 = client1.transport.update_site._session + session2 = client2.transport.update_site._session + assert session1 != session2 + session1 = client1.transport.batch_update_sites._session + session2 = client2.transport.batch_update_sites._session + assert session1 != session2 + session1 = client1.transport.batch_deactivate_sites._session + session2 = client2.transport.batch_deactivate_sites._session + assert session1 != session2 + session1 = client1.transport.batch_submit_sites_for_approval._session + session2 = client2.transport.batch_submit_sites_for_approval._session + assert session1 != session2 + + +def test_network_path(): + network_code = "squid" + expected = "networks/{network_code}".format( + network_code=network_code, + ) + actual = SiteServiceClient.network_path(network_code) + assert expected == actual + + +def test_parse_network_path(): + expected = { + "network_code": "clam", + } + path = SiteServiceClient.network_path(**expected) + + # Check that the path construction is reversible. + actual = SiteServiceClient.parse_network_path(path) + assert expected == actual + + +def test_site_path(): + network_code = "whelk" + site = "octopus" + expected = "networks/{network_code}/sites/{site}".format( + network_code=network_code, + site=site, + ) + actual = SiteServiceClient.site_path(network_code, site) + assert expected == actual + + +def test_parse_site_path(): + expected = { + "network_code": "oyster", + "site": "nudibranch", + } + path = SiteServiceClient.site_path(**expected) + + # Check that the path construction is reversible. + actual = SiteServiceClient.parse_site_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = SiteServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = SiteServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = SiteServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = SiteServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = SiteServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = SiteServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = SiteServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = SiteServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = SiteServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format( + project=project, + ) + actual = SiteServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = SiteServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = SiteServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = SiteServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = SiteServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = SiteServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.SiteServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.SiteServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = SiteServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_rest(): + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + ] + for transport in transports: + client = SiteServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (SiteServiceClient, transports.SiteServiceRestTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_team_service.py b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_team_service.py new file mode 100644 index 000000000000..b28f05d1fe73 --- /dev/null +++ b/packages/google-ads-admanager/tests/unit/gapic/admanager_v1/test_team_service.py @@ -0,0 +1,4445 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore + +from google.ads.admanager_v1.services.team_service import ( + TeamServiceClient, + pagers, + transports, +) +from google.ads.admanager_v1.types import team_enums, team_messages, team_service + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert TeamServiceClient._get_default_mtls_endpoint(None) is None + assert ( + TeamServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + ) + assert ( + TeamServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + TeamServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + TeamServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert TeamServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +def test__read_environment_variables(): + assert TeamServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert TeamServiceClient._read_environment_variables() == (True, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert TeamServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + TeamServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert TeamServiceClient._read_environment_variables() == (False, "never", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert TeamServiceClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert TeamServiceClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + TeamServiceClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert TeamServiceClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert TeamServiceClient._get_client_cert_source(None, False) is None + assert ( + TeamServiceClient._get_client_cert_source(mock_provided_cert_source, False) + is None + ) + assert ( + TeamServiceClient._get_client_cert_source(mock_provided_cert_source, True) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + TeamServiceClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + TeamServiceClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + TeamServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(TeamServiceClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = TeamServiceClient._DEFAULT_UNIVERSE + default_endpoint = TeamServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = TeamServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + TeamServiceClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + TeamServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == TeamServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + TeamServiceClient._get_api_endpoint(None, None, default_universe, "auto") + == default_endpoint + ) + assert ( + TeamServiceClient._get_api_endpoint(None, None, default_universe, "always") + == TeamServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + TeamServiceClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == TeamServiceClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + TeamServiceClient._get_api_endpoint(None, None, mock_universe, "never") + == mock_endpoint + ) + assert ( + TeamServiceClient._get_api_endpoint(None, None, default_universe, "never") + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + TeamServiceClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + TeamServiceClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + TeamServiceClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + TeamServiceClient._get_universe_domain(None, None) + == TeamServiceClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + TeamServiceClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = TeamServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = TeamServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (TeamServiceClient, "rest"), + ], +) +def test_team_service_client_from_service_account_info(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.TeamServiceRestTransport, "rest"), + ], +) +def test_team_service_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (TeamServiceClient, "rest"), + ], +) +def test_team_service_client_from_service_account_file(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +def test_team_service_client_get_transport_class(): + transport = TeamServiceClient.get_transport_class() + available_transports = [ + transports.TeamServiceRestTransport, + ] + assert transport in available_transports + + transport = TeamServiceClient.get_transport_class("rest") + assert transport == transports.TeamServiceRestTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (TeamServiceClient, transports.TeamServiceRestTransport, "rest"), + ], +) +@mock.patch.object( + TeamServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(TeamServiceClient), +) +def test_team_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(TeamServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(TeamServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + (TeamServiceClient, transports.TeamServiceRestTransport, "rest", "true"), + (TeamServiceClient, transports.TeamServiceRestTransport, "rest", "false"), + ], +) +@mock.patch.object( + TeamServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(TeamServiceClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_team_service_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [TeamServiceClient]) +@mock.patch.object( + TeamServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(TeamServiceClient) +) +def test_team_service_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize("client_class", [TeamServiceClient]) +@mock.patch.object( + TeamServiceClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(TeamServiceClient), +) +def test_team_service_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = TeamServiceClient._DEFAULT_UNIVERSE + default_endpoint = TeamServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = TeamServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (TeamServiceClient, transports.TeamServiceRestTransport, "rest"), + ], +) +def test_team_service_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + (TeamServiceClient, transports.TeamServiceRestTransport, "rest", None), + ], +) +def test_team_service_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_get_team_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_team in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_team] = mock_rpc + + request = {} + client.get_team(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_team(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_team_rest_required_fields(request_type=team_service.GetTeamRequest): + transport_class = transports.TeamServiceRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_team._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_team._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = team_messages.Team() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = team_messages.Team.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_team(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_team_rest_unset_required_fields(): + transport = transports.TeamServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_team._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_team_rest_flattened(): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = team_messages.Team() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "networks/sample1/teams/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = team_messages.Team.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_team(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=networks/*/teams/*}" % client.transport._host, args[1] + ) + + +def test_get_team_rest_flattened_error(transport: str = "rest"): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_team( + team_service.GetTeamRequest(), + name="name_value", + ) + + +def test_list_teams_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_teams in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_teams] = mock_rpc + + request = {} + client.list_teams(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_teams(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_teams_rest_required_fields(request_type=team_service.ListTeamsRequest): + transport_class = transports.TeamServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_teams._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_teams._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "order_by", + "page_size", + "page_token", + "skip", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = team_service.ListTeamsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = team_service.ListTeamsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_teams(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_teams_rest_unset_required_fields(): + transport = transports.TeamServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_teams._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "orderBy", + "pageSize", + "pageToken", + "skip", + ) + ) + & set(("parent",)) + ) + + +def test_list_teams_rest_flattened(): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = team_service.ListTeamsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = team_service.ListTeamsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_teams(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/teams" % client.transport._host, args[1] + ) + + +def test_list_teams_rest_flattened_error(transport: str = "rest"): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_teams( + team_service.ListTeamsRequest(), + parent="parent_value", + ) + + +def test_list_teams_rest_pager(transport: str = "rest"): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + team_service.ListTeamsResponse( + teams=[ + team_messages.Team(), + team_messages.Team(), + team_messages.Team(), + ], + next_page_token="abc", + ), + team_service.ListTeamsResponse( + teams=[], + next_page_token="def", + ), + team_service.ListTeamsResponse( + teams=[ + team_messages.Team(), + ], + next_page_token="ghi", + ), + team_service.ListTeamsResponse( + teams=[ + team_messages.Team(), + team_messages.Team(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(team_service.ListTeamsResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "networks/sample1"} + + pager = client.list_teams(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, team_messages.Team) for i in results) + + pages = list(client.list_teams(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_create_team_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.create_team in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.create_team] = mock_rpc + + request = {} + client.create_team(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.create_team(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_team_rest_required_fields(request_type=team_service.CreateTeamRequest): + transport_class = transports.TeamServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_team._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_team._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = team_messages.Team() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = team_messages.Team.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.create_team(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_create_team_rest_unset_required_fields(): + transport = transports.TeamServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_team._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "team", + ) + ) + ) + + +def test_create_team_rest_flattened(): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = team_messages.Team() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + team=team_messages.Team(name="name_value"), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = team_messages.Team.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.create_team(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/teams" % client.transport._host, args[1] + ) + + +def test_create_team_rest_flattened_error(transport: str = "rest"): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_team( + team_service.CreateTeamRequest(), + parent="parent_value", + team=team_messages.Team(name="name_value"), + ) + + +def test_batch_create_teams_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_create_teams in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_create_teams + ] = mock_rpc + + request = {} + client.batch_create_teams(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_create_teams(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_create_teams_rest_required_fields( + request_type=team_service.BatchCreateTeamsRequest, +): + transport_class = transports.TeamServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_create_teams._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_create_teams._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = team_service.BatchCreateTeamsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = team_service.BatchCreateTeamsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_create_teams(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_create_teams_rest_unset_required_fields(): + transport = transports.TeamServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_create_teams._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "requests", + ) + ) + ) + + +def test_batch_create_teams_rest_flattened(): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = team_service.BatchCreateTeamsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + requests=[team_service.CreateTeamRequest(parent="parent_value")], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = team_service.BatchCreateTeamsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.batch_create_teams(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/teams:batchCreate" % client.transport._host, + args[1], + ) + + +def test_batch_create_teams_rest_flattened_error(transport: str = "rest"): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_create_teams( + team_service.BatchCreateTeamsRequest(), + parent="parent_value", + requests=[team_service.CreateTeamRequest(parent="parent_value")], + ) + + +def test_update_team_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.update_team in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.update_team] = mock_rpc + + request = {} + client.update_team(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_team(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_update_team_rest_required_fields(request_type=team_service.UpdateTeamRequest): + transport_class = transports.TeamServiceRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_team._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_team._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = team_messages.Team() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = team_messages.Team.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.update_team(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_team_rest_unset_required_fields(): + transport = transports.TeamServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_team._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("updateMask",)) + & set( + ( + "team", + "updateMask", + ) + ) + ) + + +def test_update_team_rest_flattened(): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = team_messages.Team() + + # get arguments that satisfy an http rule for this method + sample_request = {"team": {"name": "networks/sample1/teams/sample2"}} + + # get truthy value for each flattened field + mock_args = dict( + team=team_messages.Team(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = team_messages.Team.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.update_team(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{team.name=networks/*/teams/*}" % client.transport._host, args[1] + ) + + +def test_update_team_rest_flattened_error(transport: str = "rest"): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_team( + team_service.UpdateTeamRequest(), + team=team_messages.Team(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_batch_update_teams_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_update_teams in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_update_teams + ] = mock_rpc + + request = {} + client.batch_update_teams(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_update_teams(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_update_teams_rest_required_fields( + request_type=team_service.BatchUpdateTeamsRequest, +): + transport_class = transports.TeamServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_update_teams._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_update_teams._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = team_service.BatchUpdateTeamsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = team_service.BatchUpdateTeamsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_update_teams(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_update_teams_rest_unset_required_fields(): + transport = transports.TeamServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_update_teams._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "requests", + ) + ) + ) + + +def test_batch_update_teams_rest_flattened(): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = team_service.BatchUpdateTeamsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + requests=[ + team_service.UpdateTeamRequest( + team=team_messages.Team(name="name_value") + ) + ], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = team_service.BatchUpdateTeamsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.batch_update_teams(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/teams:batchUpdate" % client.transport._host, + args[1], + ) + + +def test_batch_update_teams_rest_flattened_error(transport: str = "rest"): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_update_teams( + team_service.BatchUpdateTeamsRequest(), + parent="parent_value", + requests=[ + team_service.UpdateTeamRequest( + team=team_messages.Team(name="name_value") + ) + ], + ) + + +def test_batch_activate_teams_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_activate_teams in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_activate_teams + ] = mock_rpc + + request = {} + client.batch_activate_teams(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_activate_teams(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_activate_teams_rest_required_fields( + request_type=team_service.BatchActivateTeamsRequest, +): + transport_class = transports.TeamServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["names"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_activate_teams._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + jsonified_request["names"] = "names_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_activate_teams._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "names" in jsonified_request + assert jsonified_request["names"] == "names_value" + + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = team_service.BatchActivateTeamsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = team_service.BatchActivateTeamsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_activate_teams(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_activate_teams_rest_unset_required_fields(): + transport = transports.TeamServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_activate_teams._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "names", + ) + ) + ) + + +def test_batch_activate_teams_rest_flattened(): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = team_service.BatchActivateTeamsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + names=["names_value"], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = team_service.BatchActivateTeamsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.batch_activate_teams(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/teams:batchActivate" % client.transport._host, + args[1], + ) + + +def test_batch_activate_teams_rest_flattened_error(transport: str = "rest"): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_activate_teams( + team_service.BatchActivateTeamsRequest(), + parent="parent_value", + names=["names_value"], + ) + + +def test_batch_deactivate_teams_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.batch_deactivate_teams + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.batch_deactivate_teams + ] = mock_rpc + + request = {} + client.batch_deactivate_teams(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.batch_deactivate_teams(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_batch_deactivate_teams_rest_required_fields( + request_type=team_service.BatchDeactivateTeamsRequest, +): + transport_class = transports.TeamServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["names"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_deactivate_teams._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + jsonified_request["names"] = "names_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).batch_deactivate_teams._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "names" in jsonified_request + assert jsonified_request["names"] == "names_value" + + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = team_service.BatchDeactivateTeamsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = team_service.BatchDeactivateTeamsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.batch_deactivate_teams(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_batch_deactivate_teams_rest_unset_required_fields(): + transport = transports.TeamServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.batch_deactivate_teams._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "names", + ) + ) + ) + + +def test_batch_deactivate_teams_rest_flattened(): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = team_service.BatchDeactivateTeamsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "networks/sample1"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + names=["names_value"], + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = team_service.BatchDeactivateTeamsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.batch_deactivate_teams(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=networks/*}/teams:batchDeactivate" % client.transport._host, + args[1], + ) + + +def test_batch_deactivate_teams_rest_flattened_error(transport: str = "rest"): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.batch_deactivate_teams( + team_service.BatchDeactivateTeamsRequest(), + parent="parent_value", + names=["names_value"], + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.TeamServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.TeamServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = TeamServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.TeamServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = TeamServiceClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = TeamServiceClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.TeamServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = TeamServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.TeamServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = TeamServiceClient(transport=transport) + assert client.transport is transport + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.TeamServiceRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_rest(): + transport = TeamServiceClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_get_team_rest_bad_request(request_type=team_service.GetTeamRequest): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/teams/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_team(request) + + +@pytest.mark.parametrize( + "request_type", + [ + team_service.GetTeamRequest, + dict, + ], +) +def test_get_team_rest_call_success(request_type): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "networks/sample1/teams/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = team_messages.Team( + name="name_value", + display_name="display_name_value", + description="description_value", + status=team_enums.TeamStatusEnum.TeamStatus.ACTIVE, + all_companies_access=True, + all_inventory_access=True, + access_type=team_enums.TeamAccessTypeEnum.TeamAccessType.NONE, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = team_messages.Team.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_team(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, team_messages.Team) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.status == team_enums.TeamStatusEnum.TeamStatus.ACTIVE + assert response.all_companies_access is True + assert response.all_inventory_access is True + assert response.access_type == team_enums.TeamAccessTypeEnum.TeamAccessType.NONE + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_team_rest_interceptors(null_interceptor): + transport = transports.TeamServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.TeamServiceRestInterceptor(), + ) + client = TeamServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.TeamServiceRestInterceptor, "post_get_team" + ) as post, mock.patch.object( + transports.TeamServiceRestInterceptor, "post_get_team_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.TeamServiceRestInterceptor, "pre_get_team" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = team_service.GetTeamRequest.pb(team_service.GetTeamRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = team_messages.Team.to_json(team_messages.Team()) + req.return_value.content = return_value + + request = team_service.GetTeamRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = team_messages.Team() + post_with_metadata.return_value = team_messages.Team(), metadata + + client.get_team( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_teams_rest_bad_request(request_type=team_service.ListTeamsRequest): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_teams(request) + + +@pytest.mark.parametrize( + "request_type", + [ + team_service.ListTeamsRequest, + dict, + ], +) +def test_list_teams_rest_call_success(request_type): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = team_service.ListTeamsResponse( + next_page_token="next_page_token_value", + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = team_service.ListTeamsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_teams(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListTeamsPager) + assert response.next_page_token == "next_page_token_value" + assert response.total_size == 1086 + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_teams_rest_interceptors(null_interceptor): + transport = transports.TeamServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.TeamServiceRestInterceptor(), + ) + client = TeamServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.TeamServiceRestInterceptor, "post_list_teams" + ) as post, mock.patch.object( + transports.TeamServiceRestInterceptor, "post_list_teams_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.TeamServiceRestInterceptor, "pre_list_teams" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = team_service.ListTeamsRequest.pb(team_service.ListTeamsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = team_service.ListTeamsResponse.to_json( + team_service.ListTeamsResponse() + ) + req.return_value.content = return_value + + request = team_service.ListTeamsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = team_service.ListTeamsResponse() + post_with_metadata.return_value = team_service.ListTeamsResponse(), metadata + + client.list_teams( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_create_team_rest_bad_request(request_type=team_service.CreateTeamRequest): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.create_team(request) + + +@pytest.mark.parametrize( + "request_type", + [ + team_service.CreateTeamRequest, + dict, + ], +) +def test_create_team_rest_call_success(request_type): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request_init["team"] = { + "name": "name_value", + "display_name": "display_name_value", + "description": "description_value", + "status": 1, + "all_companies_access": True, + "all_inventory_access": True, + "access_type": 1, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = team_service.CreateTeamRequest.meta.fields["team"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["team"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["team"][field])): + del request_init["team"][field][i][subfield] + else: + del request_init["team"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = team_messages.Team( + name="name_value", + display_name="display_name_value", + description="description_value", + status=team_enums.TeamStatusEnum.TeamStatus.ACTIVE, + all_companies_access=True, + all_inventory_access=True, + access_type=team_enums.TeamAccessTypeEnum.TeamAccessType.NONE, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = team_messages.Team.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.create_team(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, team_messages.Team) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.status == team_enums.TeamStatusEnum.TeamStatus.ACTIVE + assert response.all_companies_access is True + assert response.all_inventory_access is True + assert response.access_type == team_enums.TeamAccessTypeEnum.TeamAccessType.NONE + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_team_rest_interceptors(null_interceptor): + transport = transports.TeamServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.TeamServiceRestInterceptor(), + ) + client = TeamServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.TeamServiceRestInterceptor, "post_create_team" + ) as post, mock.patch.object( + transports.TeamServiceRestInterceptor, "post_create_team_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.TeamServiceRestInterceptor, "pre_create_team" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = team_service.CreateTeamRequest.pb(team_service.CreateTeamRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = team_messages.Team.to_json(team_messages.Team()) + req.return_value.content = return_value + + request = team_service.CreateTeamRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = team_messages.Team() + post_with_metadata.return_value = team_messages.Team(), metadata + + client.create_team( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_batch_create_teams_rest_bad_request( + request_type=team_service.BatchCreateTeamsRequest, +): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.batch_create_teams(request) + + +@pytest.mark.parametrize( + "request_type", + [ + team_service.BatchCreateTeamsRequest, + dict, + ], +) +def test_batch_create_teams_rest_call_success(request_type): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = team_service.BatchCreateTeamsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = team_service.BatchCreateTeamsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.batch_create_teams(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, team_service.BatchCreateTeamsResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_create_teams_rest_interceptors(null_interceptor): + transport = transports.TeamServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.TeamServiceRestInterceptor(), + ) + client = TeamServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.TeamServiceRestInterceptor, "post_batch_create_teams" + ) as post, mock.patch.object( + transports.TeamServiceRestInterceptor, "post_batch_create_teams_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.TeamServiceRestInterceptor, "pre_batch_create_teams" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = team_service.BatchCreateTeamsRequest.pb( + team_service.BatchCreateTeamsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = team_service.BatchCreateTeamsResponse.to_json( + team_service.BatchCreateTeamsResponse() + ) + req.return_value.content = return_value + + request = team_service.BatchCreateTeamsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = team_service.BatchCreateTeamsResponse() + post_with_metadata.return_value = ( + team_service.BatchCreateTeamsResponse(), + metadata, + ) + + client.batch_create_teams( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_update_team_rest_bad_request(request_type=team_service.UpdateTeamRequest): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"team": {"name": "networks/sample1/teams/sample2"}} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.update_team(request) + + +@pytest.mark.parametrize( + "request_type", + [ + team_service.UpdateTeamRequest, + dict, + ], +) +def test_update_team_rest_call_success(request_type): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"team": {"name": "networks/sample1/teams/sample2"}} + request_init["team"] = { + "name": "networks/sample1/teams/sample2", + "display_name": "display_name_value", + "description": "description_value", + "status": 1, + "all_companies_access": True, + "all_inventory_access": True, + "access_type": 1, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = team_service.UpdateTeamRequest.meta.fields["team"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["team"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["team"][field])): + del request_init["team"][field][i][subfield] + else: + del request_init["team"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = team_messages.Team( + name="name_value", + display_name="display_name_value", + description="description_value", + status=team_enums.TeamStatusEnum.TeamStatus.ACTIVE, + all_companies_access=True, + all_inventory_access=True, + access_type=team_enums.TeamAccessTypeEnum.TeamAccessType.NONE, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = team_messages.Team.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.update_team(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, team_messages.Team) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.status == team_enums.TeamStatusEnum.TeamStatus.ACTIVE + assert response.all_companies_access is True + assert response.all_inventory_access is True + assert response.access_type == team_enums.TeamAccessTypeEnum.TeamAccessType.NONE + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_team_rest_interceptors(null_interceptor): + transport = transports.TeamServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.TeamServiceRestInterceptor(), + ) + client = TeamServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.TeamServiceRestInterceptor, "post_update_team" + ) as post, mock.patch.object( + transports.TeamServiceRestInterceptor, "post_update_team_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.TeamServiceRestInterceptor, "pre_update_team" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = team_service.UpdateTeamRequest.pb(team_service.UpdateTeamRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = team_messages.Team.to_json(team_messages.Team()) + req.return_value.content = return_value + + request = team_service.UpdateTeamRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = team_messages.Team() + post_with_metadata.return_value = team_messages.Team(), metadata + + client.update_team( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_batch_update_teams_rest_bad_request( + request_type=team_service.BatchUpdateTeamsRequest, +): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.batch_update_teams(request) + + +@pytest.mark.parametrize( + "request_type", + [ + team_service.BatchUpdateTeamsRequest, + dict, + ], +) +def test_batch_update_teams_rest_call_success(request_type): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = team_service.BatchUpdateTeamsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = team_service.BatchUpdateTeamsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.batch_update_teams(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, team_service.BatchUpdateTeamsResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_update_teams_rest_interceptors(null_interceptor): + transport = transports.TeamServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.TeamServiceRestInterceptor(), + ) + client = TeamServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.TeamServiceRestInterceptor, "post_batch_update_teams" + ) as post, mock.patch.object( + transports.TeamServiceRestInterceptor, "post_batch_update_teams_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.TeamServiceRestInterceptor, "pre_batch_update_teams" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = team_service.BatchUpdateTeamsRequest.pb( + team_service.BatchUpdateTeamsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = team_service.BatchUpdateTeamsResponse.to_json( + team_service.BatchUpdateTeamsResponse() + ) + req.return_value.content = return_value + + request = team_service.BatchUpdateTeamsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = team_service.BatchUpdateTeamsResponse() + post_with_metadata.return_value = ( + team_service.BatchUpdateTeamsResponse(), + metadata, + ) + + client.batch_update_teams( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_batch_activate_teams_rest_bad_request( + request_type=team_service.BatchActivateTeamsRequest, +): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.batch_activate_teams(request) + + +@pytest.mark.parametrize( + "request_type", + [ + team_service.BatchActivateTeamsRequest, + dict, + ], +) +def test_batch_activate_teams_rest_call_success(request_type): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = team_service.BatchActivateTeamsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = team_service.BatchActivateTeamsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.batch_activate_teams(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, team_service.BatchActivateTeamsResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_activate_teams_rest_interceptors(null_interceptor): + transport = transports.TeamServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.TeamServiceRestInterceptor(), + ) + client = TeamServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.TeamServiceRestInterceptor, "post_batch_activate_teams" + ) as post, mock.patch.object( + transports.TeamServiceRestInterceptor, "post_batch_activate_teams_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.TeamServiceRestInterceptor, "pre_batch_activate_teams" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = team_service.BatchActivateTeamsRequest.pb( + team_service.BatchActivateTeamsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = team_service.BatchActivateTeamsResponse.to_json( + team_service.BatchActivateTeamsResponse() + ) + req.return_value.content = return_value + + request = team_service.BatchActivateTeamsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = team_service.BatchActivateTeamsResponse() + post_with_metadata.return_value = ( + team_service.BatchActivateTeamsResponse(), + metadata, + ) + + client.batch_activate_teams( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_batch_deactivate_teams_rest_bad_request( + request_type=team_service.BatchDeactivateTeamsRequest, +): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.batch_deactivate_teams(request) + + +@pytest.mark.parametrize( + "request_type", + [ + team_service.BatchDeactivateTeamsRequest, + dict, + ], +) +def test_batch_deactivate_teams_rest_call_success(request_type): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "networks/sample1"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = team_service.BatchDeactivateTeamsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = team_service.BatchDeactivateTeamsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.batch_deactivate_teams(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, team_service.BatchDeactivateTeamsResponse) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_deactivate_teams_rest_interceptors(null_interceptor): + transport = transports.TeamServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.TeamServiceRestInterceptor(), + ) + client = TeamServiceClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.TeamServiceRestInterceptor, "post_batch_deactivate_teams" + ) as post, mock.patch.object( + transports.TeamServiceRestInterceptor, + "post_batch_deactivate_teams_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.TeamServiceRestInterceptor, "pre_batch_deactivate_teams" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = team_service.BatchDeactivateTeamsRequest.pb( + team_service.BatchDeactivateTeamsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = team_service.BatchDeactivateTeamsResponse.to_json( + team_service.BatchDeactivateTeamsResponse() + ) + req.return_value.content = return_value + + request = team_service.BatchDeactivateTeamsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = team_service.BatchDeactivateTeamsResponse() + post_with_metadata.return_value = ( + team_service.BatchDeactivateTeamsResponse(), + metadata, + ) + + client.batch_deactivate_teams( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "networks/sample1/operations/reports/runs/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "networks/sample1/operations/reports/runs/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_initialize_client_w_rest(): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_team_empty_call_rest(): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_team), "__call__") as call: + client.get_team(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = team_service.GetTeamRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_teams_empty_call_rest(): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_teams), "__call__") as call: + client.list_teams(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = team_service.ListTeamsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_team_empty_call_rest(): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_team), "__call__") as call: + client.create_team(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = team_service.CreateTeamRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_create_teams_empty_call_rest(): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_create_teams), "__call__" + ) as call: + client.batch_create_teams(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = team_service.BatchCreateTeamsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_team_empty_call_rest(): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_team), "__call__") as call: + client.update_team(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = team_service.UpdateTeamRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_update_teams_empty_call_rest(): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_update_teams), "__call__" + ) as call: + client.batch_update_teams(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = team_service.BatchUpdateTeamsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_activate_teams_empty_call_rest(): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_activate_teams), "__call__" + ) as call: + client.batch_activate_teams(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = team_service.BatchActivateTeamsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_batch_deactivate_teams_empty_call_rest(): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.batch_deactivate_teams), "__call__" + ) as call: + client.batch_deactivate_teams(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = team_service.BatchDeactivateTeamsRequest() + + assert args[0] == request_msg + + +def test_team_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.TeamServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_team_service_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.ads.admanager_v1.services.team_service.transports.TeamServiceTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.TeamServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "get_team", + "list_teams", + "create_team", + "batch_create_teams", + "update_team", + "batch_update_teams", + "batch_activate_teams", + "batch_deactivate_teams", + "get_operation", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_team_service_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.ads.admanager_v1.services.team_service.transports.TeamServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.TeamServiceTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id="octopus", + ) + + +def test_team_service_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.ads.admanager_v1.services.team_service.transports.TeamServiceTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.TeamServiceTransport() + adc.assert_called_once() + + +def test_team_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + TeamServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=("https://www.googleapis.com/auth/admanager",), + quota_project_id=None, + ) + + +def test_team_service_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.TeamServiceRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_team_service_host_no_port(transport_name): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_team_service_host_with_port(transport_name): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="admanager.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "admanager.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://admanager.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_team_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = TeamServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = TeamServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.get_team._session + session2 = client2.transport.get_team._session + assert session1 != session2 + session1 = client1.transport.list_teams._session + session2 = client2.transport.list_teams._session + assert session1 != session2 + session1 = client1.transport.create_team._session + session2 = client2.transport.create_team._session + assert session1 != session2 + session1 = client1.transport.batch_create_teams._session + session2 = client2.transport.batch_create_teams._session + assert session1 != session2 + session1 = client1.transport.update_team._session + session2 = client2.transport.update_team._session + assert session1 != session2 + session1 = client1.transport.batch_update_teams._session + session2 = client2.transport.batch_update_teams._session + assert session1 != session2 + session1 = client1.transport.batch_activate_teams._session + session2 = client2.transport.batch_activate_teams._session + assert session1 != session2 + session1 = client1.transport.batch_deactivate_teams._session + session2 = client2.transport.batch_deactivate_teams._session + assert session1 != session2 + + +def test_network_path(): + network_code = "squid" + expected = "networks/{network_code}".format( + network_code=network_code, + ) + actual = TeamServiceClient.network_path(network_code) + assert expected == actual + + +def test_parse_network_path(): + expected = { + "network_code": "clam", + } + path = TeamServiceClient.network_path(**expected) + + # Check that the path construction is reversible. + actual = TeamServiceClient.parse_network_path(path) + assert expected == actual + + +def test_team_path(): + network_code = "whelk" + team = "octopus" + expected = "networks/{network_code}/teams/{team}".format( + network_code=network_code, + team=team, + ) + actual = TeamServiceClient.team_path(network_code, team) + assert expected == actual + + +def test_parse_team_path(): + expected = { + "network_code": "oyster", + "team": "nudibranch", + } + path = TeamServiceClient.team_path(**expected) + + # Check that the path construction is reversible. + actual = TeamServiceClient.parse_team_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = TeamServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = TeamServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = TeamServiceClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = TeamServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = TeamServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = TeamServiceClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = TeamServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = TeamServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = TeamServiceClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format( + project=project, + ) + actual = TeamServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = TeamServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = TeamServiceClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = TeamServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = TeamServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = TeamServiceClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.TeamServiceTransport, "_prep_wrapped_messages" + ) as prep: + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.TeamServiceTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = TeamServiceClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_transport_close_rest(): + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + ] + for transport in transports: + client = TeamServiceClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (TeamServiceClient, transports.TeamServiceRestTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-apps-chat/google/apps/chat_v1/types/deletion_metadata.py b/packages/google-apps-chat/google/apps/chat_v1/types/deletion_metadata.py index eb92ab43eb18..6603304076c4 100644 --- a/packages/google-apps-chat/google/apps/chat_v1/types/deletion_metadata.py +++ b/packages/google-apps-chat/google/apps/chat_v1/types/deletion_metadata.py @@ -48,7 +48,7 @@ class DeletionType(proto.Enum): CREATOR (1): User deleted their own message. SPACE_OWNER (2): - A space manager deleted the message. + An owner or manager deleted the message. ADMIN (3): A Google Workspace administrator deleted the message. Administrators can delete any message diff --git a/packages/google-apps-chat/google/apps/chat_v1/types/membership.py b/packages/google-apps-chat/google/apps/chat_v1/types/membership.py index e33515873a43..6888a1eddaeb 100644 --- a/packages/google-apps-chat/google/apps/chat_v1/types/membership.py +++ b/packages/google-apps-chat/google/apps/chat_v1/types/membership.py @@ -130,19 +130,73 @@ class MembershipRole(proto.Enum): always assigned this role (other enum values might be used in the future). ROLE_MEMBER (1): - A member of the space. The user has basic - permissions, like sending messages to the space. - In 1:1 and unnamed group conversations, everyone + A member of the space. In the Chat UI, this role is called + Member. + + The user has basic permissions, like sending messages to the + space. Managers and owners can grant members additional + permissions in a space, including: + + - Add or remove members. + - Modify space details. + - Turn history on or off. + - Mention everyone in the space with ``@all``. + - Manage Chat apps and webhooks installed in the space. + + In direct messages and unnamed group conversations, everyone has this role. ROLE_MANAGER (2): - A space manager. The user has all basic permissions plus - administrative permissions that let them manage the space, - like adding or removing members. Only supported in - [SpaceType.SPACE][google.chat.v1.Space.SpaceType]. + A space owner. In the Chat UI, this role is called Owner. + + The user has the complete set of space permissions to manage + the space, including: + + - Change the role of other members in the space to member, + manager, or owner. + - Delete the space. + + Only supported in + [SpaceType.SPACE][google.chat.v1.Space.SpaceType] (named + spaces). + + To learn more, see `Learn more about your role as a space + owner or + manager `__. + ROLE_ASSISTANT_MANAGER (4): + A space manager. In the Chat UI, this role is called + Manager. + + The user has all basic permissions of ``ROLE_MEMBER``, and + can be granted a subset of administrative permissions by an + owner. By default, managers have all the permissions of an + owner except for the ability to: + + - Delete the space. + - Make another space member an owner. + - Change an owner's role. + + By default, managers permissions include but aren't limited + to: + + - Make another member a manager. + - Delete messages in the space. + - Manage space permissions. + - Receive notifications for requests to join the space if + the manager has the "manage members" permission in the + space settings. + - Make a space discoverable. + + Only supported in + [SpaceType.SPACE][google.chat.v1.Space.SpaceType] (named + spaces). + + To learn more, see `Manage space + settings `__. """ MEMBERSHIP_ROLE_UNSPECIFIED = 0 ROLE_MEMBER = 1 ROLE_MANAGER = 2 + ROLE_ASSISTANT_MANAGER = 4 name: str = proto.Field( proto.STRING, diff --git a/packages/google-apps-chat/google/apps/chat_v1/types/space.py b/packages/google-apps-chat/google/apps/chat_v1/types/space.py index e506cc9543f1..d0e643e163e0 100644 --- a/packages/google-apps-chat/google/apps/chat_v1/types/space.py +++ b/packages/google-apps-chat/google/apps/chat_v1/types/space.py @@ -539,19 +539,34 @@ class PermissionSettings(proto.Message): class PermissionSetting(proto.Message): r"""Represents a space permission setting. + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: managers_allowed (bool): - Optional. Whether spaces managers have this - permission. + Optional. Whether space owners + ([``ROLE_MANAGER``][google.chat.v1.Membership.MembershipRole.ROLE_MANAGER]) + have this permission. + assistant_managers_allowed (bool): + Optional. Whether space managers + [``ROLE_ASSISTANT_MANAGER``][google.chat.v1.Membership.MembershipRole.ROLE_ASSISTANT_MANAGER]) + have this permission. + + This field is a member of `oneof`_ ``_assistant_managers_allowed``. members_allowed (bool): - Optional. Whether non-manager members have - this permission. + Optional. Whether basic space members + ([``ROLE_MEMBER``][google.chat.v1.Membership.MembershipRole.ROLE_MEMBER]) + have this permission. """ managers_allowed: bool = proto.Field( proto.BOOL, number=1, ) + assistant_managers_allowed: bool = proto.Field( + proto.BOOL, + number=3, + optional=True, + ) members_allowed: bool = proto.Field( proto.BOOL, number=2, diff --git a/packages/google-apps-chat/noxfile.py b/packages/google-apps-chat/noxfile.py index b3d9cc17d016..a237afad67d3 100644 --- a/packages/google-apps-chat/noxfile.py +++ b/packages/google-apps-chat/noxfile.py @@ -27,6 +27,10 @@ LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] +# Add samples to the list of directories to format if the directory exists. +if os.path.isdir("samples"): + LINT_PATHS.append("samples") + ALL_PYTHON = [ "3.7", "3.8", diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_complete_import_space_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_complete_import_space_async.py index 680f8ee1abef..89cec37005bd 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_complete_import_space_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_complete_import_space_async.py @@ -49,4 +49,5 @@ async def sample_complete_import_space(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_CompleteImportSpace_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_complete_import_space_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_complete_import_space_sync.py index 7bebc5aefb47..8ed4b91beaf6 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_complete_import_space_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_complete_import_space_sync.py @@ -49,4 +49,5 @@ def sample_complete_import_space(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_CompleteImportSpace_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_custom_emoji_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_custom_emoji_async.py index 335a0f0f175e..d107d0550478 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_custom_emoji_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_custom_emoji_async.py @@ -39,8 +39,7 @@ async def sample_create_custom_emoji(): client = chat_v1.ChatServiceAsyncClient() # Initialize request argument(s) - request = chat_v1.CreateCustomEmojiRequest( - ) + request = chat_v1.CreateCustomEmojiRequest() # Make the request response = await client.create_custom_emoji(request=request) @@ -48,4 +47,5 @@ async def sample_create_custom_emoji(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_CreateCustomEmoji_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_custom_emoji_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_custom_emoji_sync.py index 0fbe93dc02bc..d69eaa6b80c5 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_custom_emoji_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_custom_emoji_sync.py @@ -39,8 +39,7 @@ def sample_create_custom_emoji(): client = chat_v1.ChatServiceClient() # Initialize request argument(s) - request = chat_v1.CreateCustomEmojiRequest( - ) + request = chat_v1.CreateCustomEmojiRequest() # Make the request response = client.create_custom_emoji(request=request) @@ -48,4 +47,5 @@ def sample_create_custom_emoji(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_CreateCustomEmoji_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_membership_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_membership_async.py index 7c92e91cd929..6acba08450fc 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_membership_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_membership_async.py @@ -49,4 +49,5 @@ async def sample_create_membership(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_CreateMembership_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_membership_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_membership_sync.py index 0856ac26f561..a0392c8fb723 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_membership_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_membership_sync.py @@ -49,4 +49,5 @@ def sample_create_membership(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_CreateMembership_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_message_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_message_async.py index d98817f376fa..e36d4dbfdb59 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_message_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_message_async.py @@ -49,4 +49,5 @@ async def sample_create_message(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_CreateMessage_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_message_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_message_sync.py index e9bef8fa06d0..e8ab4845d67b 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_message_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_message_sync.py @@ -49,4 +49,5 @@ def sample_create_message(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_CreateMessage_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_reaction_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_reaction_async.py index e77f43abaed0..48f4e65961bf 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_reaction_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_reaction_async.py @@ -53,4 +53,5 @@ async def sample_create_reaction(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_CreateReaction_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_reaction_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_reaction_sync.py index d656af84c86d..f6177f2af18c 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_reaction_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_reaction_sync.py @@ -53,4 +53,5 @@ def sample_create_reaction(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_CreateReaction_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_space_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_space_async.py index 07469d8f244f..4a468cb5e3e6 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_space_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_space_async.py @@ -52,4 +52,5 @@ async def sample_create_space(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_CreateSpace_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_space_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_space_sync.py index 78156ab25706..dc1c52400e8f 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_space_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_create_space_sync.py @@ -52,4 +52,5 @@ def sample_create_space(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_CreateSpace_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_delete_membership_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_delete_membership_async.py index 4bb530b2038c..d4d2ee808cda 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_delete_membership_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_delete_membership_async.py @@ -49,4 +49,5 @@ async def sample_delete_membership(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_DeleteMembership_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_delete_membership_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_delete_membership_sync.py index e7a9b7bafe9d..01ff2d25b137 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_delete_membership_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_delete_membership_sync.py @@ -49,4 +49,5 @@ def sample_delete_membership(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_DeleteMembership_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_find_direct_message_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_find_direct_message_async.py index 12619e7977f1..b7859ac8b9df 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_find_direct_message_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_find_direct_message_async.py @@ -49,4 +49,5 @@ async def sample_find_direct_message(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_FindDirectMessage_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_find_direct_message_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_find_direct_message_sync.py index a56c2e964c6f..f9c80f207a76 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_find_direct_message_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_find_direct_message_sync.py @@ -49,4 +49,5 @@ def sample_find_direct_message(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_FindDirectMessage_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_attachment_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_attachment_async.py index 8a6f4a974db7..e61a48bbb89f 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_attachment_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_attachment_async.py @@ -49,4 +49,5 @@ async def sample_get_attachment(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_GetAttachment_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_attachment_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_attachment_sync.py index 6a2da7a26700..b1f687163782 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_attachment_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_attachment_sync.py @@ -49,4 +49,5 @@ def sample_get_attachment(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_GetAttachment_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_custom_emoji_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_custom_emoji_async.py index 17f11e6fcd9b..c40f056940d5 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_custom_emoji_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_custom_emoji_async.py @@ -49,4 +49,5 @@ async def sample_get_custom_emoji(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_GetCustomEmoji_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_custom_emoji_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_custom_emoji_sync.py index 34dce29bf0ab..97881ca579b8 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_custom_emoji_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_custom_emoji_sync.py @@ -49,4 +49,5 @@ def sample_get_custom_emoji(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_GetCustomEmoji_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_membership_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_membership_async.py index c3303d20ee93..3b6548134f97 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_membership_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_membership_async.py @@ -49,4 +49,5 @@ async def sample_get_membership(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_GetMembership_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_membership_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_membership_sync.py index 6919f107003e..ff01e4a01e04 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_membership_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_membership_sync.py @@ -49,4 +49,5 @@ def sample_get_membership(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_GetMembership_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_message_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_message_async.py index 3da8044fbe02..68210a982e6d 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_message_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_message_async.py @@ -49,4 +49,5 @@ async def sample_get_message(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_GetMessage_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_message_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_message_sync.py index eea3c3c36583..dcf416262c71 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_message_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_message_sync.py @@ -49,4 +49,5 @@ def sample_get_message(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_GetMessage_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_async.py index 89608a93727d..864e5b151aea 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_async.py @@ -49,4 +49,5 @@ async def sample_get_space(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_GetSpace_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_event_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_event_async.py index 218cdf4186ab..828cb9b287d1 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_event_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_event_async.py @@ -49,4 +49,5 @@ async def sample_get_space_event(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_GetSpaceEvent_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_event_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_event_sync.py index 809cedb65807..4870c381b081 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_event_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_event_sync.py @@ -49,4 +49,5 @@ def sample_get_space_event(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_GetSpaceEvent_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_notification_setting_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_notification_setting_async.py index a089526f8979..b2c9ac34d382 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_notification_setting_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_notification_setting_async.py @@ -49,4 +49,5 @@ async def sample_get_space_notification_setting(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_GetSpaceNotificationSetting_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_notification_setting_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_notification_setting_sync.py index 6f10fe0a4b3d..1b68044d0d59 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_notification_setting_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_notification_setting_sync.py @@ -49,4 +49,5 @@ def sample_get_space_notification_setting(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_GetSpaceNotificationSetting_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_read_state_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_read_state_async.py index 3112e6a7a529..65163a6d98ef 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_read_state_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_read_state_async.py @@ -49,4 +49,5 @@ async def sample_get_space_read_state(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_GetSpaceReadState_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_read_state_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_read_state_sync.py index e62caa99585c..60a7a99c3f6a 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_read_state_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_read_state_sync.py @@ -49,4 +49,5 @@ def sample_get_space_read_state(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_GetSpaceReadState_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_sync.py index fc86b03f3e65..df80280068db 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_space_sync.py @@ -49,4 +49,5 @@ def sample_get_space(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_GetSpace_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_thread_read_state_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_thread_read_state_async.py index f8139d85bcaa..ec2fa4cca1c9 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_thread_read_state_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_thread_read_state_async.py @@ -49,4 +49,5 @@ async def sample_get_thread_read_state(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_GetThreadReadState_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_thread_read_state_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_thread_read_state_sync.py index 8ef3e826bdae..3507e0f99a72 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_thread_read_state_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_get_thread_read_state_sync.py @@ -49,4 +49,5 @@ def sample_get_thread_read_state(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_GetThreadReadState_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_custom_emojis_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_custom_emojis_async.py index 1c0b8e6d623e..d84e3aa933e2 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_custom_emojis_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_custom_emojis_async.py @@ -39,8 +39,7 @@ async def sample_list_custom_emojis(): client = chat_v1.ChatServiceAsyncClient() # Initialize request argument(s) - request = chat_v1.ListCustomEmojisRequest( - ) + request = chat_v1.ListCustomEmojisRequest() # Make the request page_result = client.list_custom_emojis(request=request) @@ -49,4 +48,5 @@ async def sample_list_custom_emojis(): async for response in page_result: print(response) + # [END chat_v1_generated_ChatService_ListCustomEmojis_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_custom_emojis_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_custom_emojis_sync.py index 2264b8123886..13cedd240b2f 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_custom_emojis_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_custom_emojis_sync.py @@ -39,8 +39,7 @@ def sample_list_custom_emojis(): client = chat_v1.ChatServiceClient() # Initialize request argument(s) - request = chat_v1.ListCustomEmojisRequest( - ) + request = chat_v1.ListCustomEmojisRequest() # Make the request page_result = client.list_custom_emojis(request=request) @@ -49,4 +48,5 @@ def sample_list_custom_emojis(): for response in page_result: print(response) + # [END chat_v1_generated_ChatService_ListCustomEmojis_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_memberships_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_memberships_async.py index c00d29bdc19a..e0bc0b0290af 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_memberships_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_memberships_async.py @@ -50,4 +50,5 @@ async def sample_list_memberships(): async for response in page_result: print(response) + # [END chat_v1_generated_ChatService_ListMemberships_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_memberships_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_memberships_sync.py index aa1d0968555c..8f46fa7184d7 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_memberships_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_memberships_sync.py @@ -50,4 +50,5 @@ def sample_list_memberships(): for response in page_result: print(response) + # [END chat_v1_generated_ChatService_ListMemberships_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_messages_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_messages_async.py index 36a52ee7650e..376399f285e6 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_messages_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_messages_async.py @@ -50,4 +50,5 @@ async def sample_list_messages(): async for response in page_result: print(response) + # [END chat_v1_generated_ChatService_ListMessages_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_messages_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_messages_sync.py index b876195c9319..ff595876b7d8 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_messages_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_messages_sync.py @@ -50,4 +50,5 @@ def sample_list_messages(): for response in page_result: print(response) + # [END chat_v1_generated_ChatService_ListMessages_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_reactions_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_reactions_async.py index 8e05ae260a5c..1364f40bea95 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_reactions_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_reactions_async.py @@ -50,4 +50,5 @@ async def sample_list_reactions(): async for response in page_result: print(response) + # [END chat_v1_generated_ChatService_ListReactions_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_reactions_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_reactions_sync.py index 741961a0269f..1ab1c6f362d9 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_reactions_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_reactions_sync.py @@ -50,4 +50,5 @@ def sample_list_reactions(): for response in page_result: print(response) + # [END chat_v1_generated_ChatService_ListReactions_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_space_events_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_space_events_async.py index bd7e0b7561d6..5d352584aef9 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_space_events_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_space_events_async.py @@ -51,4 +51,5 @@ async def sample_list_space_events(): async for response in page_result: print(response) + # [END chat_v1_generated_ChatService_ListSpaceEvents_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_space_events_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_space_events_sync.py index 876ad257dbd5..01ec344c96c7 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_space_events_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_space_events_sync.py @@ -51,4 +51,5 @@ def sample_list_space_events(): for response in page_result: print(response) + # [END chat_v1_generated_ChatService_ListSpaceEvents_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_spaces_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_spaces_async.py index 89e511153d79..57b644e8ce96 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_spaces_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_spaces_async.py @@ -39,8 +39,7 @@ async def sample_list_spaces(): client = chat_v1.ChatServiceAsyncClient() # Initialize request argument(s) - request = chat_v1.ListSpacesRequest( - ) + request = chat_v1.ListSpacesRequest() # Make the request page_result = client.list_spaces(request=request) @@ -49,4 +48,5 @@ async def sample_list_spaces(): async for response in page_result: print(response) + # [END chat_v1_generated_ChatService_ListSpaces_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_spaces_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_spaces_sync.py index b6e93d8aee4b..c9a0689448fd 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_spaces_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_list_spaces_sync.py @@ -39,8 +39,7 @@ def sample_list_spaces(): client = chat_v1.ChatServiceClient() # Initialize request argument(s) - request = chat_v1.ListSpacesRequest( - ) + request = chat_v1.ListSpacesRequest() # Make the request page_result = client.list_spaces(request=request) @@ -49,4 +48,5 @@ def sample_list_spaces(): for response in page_result: print(response) + # [END chat_v1_generated_ChatService_ListSpaces_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_search_spaces_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_search_spaces_async.py index 7f5e0cd7a2ae..cbdd00e0aa93 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_search_spaces_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_search_spaces_async.py @@ -50,4 +50,5 @@ async def sample_search_spaces(): async for response in page_result: print(response) + # [END chat_v1_generated_ChatService_SearchSpaces_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_search_spaces_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_search_spaces_sync.py index 4a6ac2be070b..1806292b8393 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_search_spaces_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_search_spaces_sync.py @@ -50,4 +50,5 @@ def sample_search_spaces(): for response in page_result: print(response) + # [END chat_v1_generated_ChatService_SearchSpaces_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_set_up_space_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_set_up_space_async.py index 4a9b29302348..78cd2fecc5d5 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_set_up_space_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_set_up_space_async.py @@ -52,4 +52,5 @@ async def sample_set_up_space(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_SetUpSpace_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_set_up_space_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_set_up_space_sync.py index a545b52eb916..242a0897b881 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_set_up_space_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_set_up_space_sync.py @@ -52,4 +52,5 @@ def sample_set_up_space(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_SetUpSpace_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_membership_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_membership_async.py index d87ea8a17b2e..85e314206101 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_membership_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_membership_async.py @@ -39,8 +39,7 @@ async def sample_update_membership(): client = chat_v1.ChatServiceAsyncClient() # Initialize request argument(s) - request = chat_v1.UpdateMembershipRequest( - ) + request = chat_v1.UpdateMembershipRequest() # Make the request response = await client.update_membership(request=request) @@ -48,4 +47,5 @@ async def sample_update_membership(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_UpdateMembership_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_membership_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_membership_sync.py index c545c11ec97d..a935f8c6f6b1 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_membership_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_membership_sync.py @@ -39,8 +39,7 @@ def sample_update_membership(): client = chat_v1.ChatServiceClient() # Initialize request argument(s) - request = chat_v1.UpdateMembershipRequest( - ) + request = chat_v1.UpdateMembershipRequest() # Make the request response = client.update_membership(request=request) @@ -48,4 +47,5 @@ def sample_update_membership(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_UpdateMembership_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_message_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_message_async.py index 5aa405ef5181..e2d0d4428a95 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_message_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_message_async.py @@ -39,8 +39,7 @@ async def sample_update_message(): client = chat_v1.ChatServiceAsyncClient() # Initialize request argument(s) - request = chat_v1.UpdateMessageRequest( - ) + request = chat_v1.UpdateMessageRequest() # Make the request response = await client.update_message(request=request) @@ -48,4 +47,5 @@ async def sample_update_message(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_UpdateMessage_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_message_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_message_sync.py index 53646edf5b21..2cc7a60537c6 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_message_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_message_sync.py @@ -39,8 +39,7 @@ def sample_update_message(): client = chat_v1.ChatServiceClient() # Initialize request argument(s) - request = chat_v1.UpdateMessageRequest( - ) + request = chat_v1.UpdateMessageRequest() # Make the request response = client.update_message(request=request) @@ -48,4 +47,5 @@ def sample_update_message(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_UpdateMessage_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_async.py index 64a9a0a21257..4cc55a376782 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_async.py @@ -52,4 +52,5 @@ async def sample_update_space(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_UpdateSpace_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_notification_setting_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_notification_setting_async.py index 7362bb3fb6f9..2e95995c7a7d 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_notification_setting_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_notification_setting_async.py @@ -39,8 +39,7 @@ async def sample_update_space_notification_setting(): client = chat_v1.ChatServiceAsyncClient() # Initialize request argument(s) - request = chat_v1.UpdateSpaceNotificationSettingRequest( - ) + request = chat_v1.UpdateSpaceNotificationSettingRequest() # Make the request response = await client.update_space_notification_setting(request=request) @@ -48,4 +47,5 @@ async def sample_update_space_notification_setting(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_UpdateSpaceNotificationSetting_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_notification_setting_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_notification_setting_sync.py index 1215b9dc7e34..dae1891a7397 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_notification_setting_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_notification_setting_sync.py @@ -39,8 +39,7 @@ def sample_update_space_notification_setting(): client = chat_v1.ChatServiceClient() # Initialize request argument(s) - request = chat_v1.UpdateSpaceNotificationSettingRequest( - ) + request = chat_v1.UpdateSpaceNotificationSettingRequest() # Make the request response = client.update_space_notification_setting(request=request) @@ -48,4 +47,5 @@ def sample_update_space_notification_setting(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_UpdateSpaceNotificationSetting_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_read_state_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_read_state_async.py index 0819285b7b08..79cb43e97d86 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_read_state_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_read_state_async.py @@ -39,8 +39,7 @@ async def sample_update_space_read_state(): client = chat_v1.ChatServiceAsyncClient() # Initialize request argument(s) - request = chat_v1.UpdateSpaceReadStateRequest( - ) + request = chat_v1.UpdateSpaceReadStateRequest() # Make the request response = await client.update_space_read_state(request=request) @@ -48,4 +47,5 @@ async def sample_update_space_read_state(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_UpdateSpaceReadState_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_read_state_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_read_state_sync.py index acd75f81cc84..b4510faa3e2d 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_read_state_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_read_state_sync.py @@ -39,8 +39,7 @@ def sample_update_space_read_state(): client = chat_v1.ChatServiceClient() # Initialize request argument(s) - request = chat_v1.UpdateSpaceReadStateRequest( - ) + request = chat_v1.UpdateSpaceReadStateRequest() # Make the request response = client.update_space_read_state(request=request) @@ -48,4 +47,5 @@ def sample_update_space_read_state(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_UpdateSpaceReadState_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_sync.py index bf5985a78b05..ceb69d42e831 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_update_space_sync.py @@ -52,4 +52,5 @@ def sample_update_space(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_UpdateSpace_sync] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_upload_attachment_async.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_upload_attachment_async.py index ed3f8f791f3c..e7d3c6208da2 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_upload_attachment_async.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_upload_attachment_async.py @@ -50,4 +50,5 @@ async def sample_upload_attachment(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_UploadAttachment_async] diff --git a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_upload_attachment_sync.py b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_upload_attachment_sync.py index f07a72dc2b09..30424d636f6e 100644 --- a/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_upload_attachment_sync.py +++ b/packages/google-apps-chat/samples/generated_samples/chat_v1_generated_chat_service_upload_attachment_sync.py @@ -50,4 +50,5 @@ def sample_upload_attachment(): # Handle the response print(response) + # [END chat_v1_generated_ChatService_UploadAttachment_sync] diff --git a/packages/google-apps-chat/setup.py b/packages/google-apps-chat/setup.py index ef15a3fde23f..e6bbc09ab33e 100644 --- a/packages/google-apps-chat/setup.py +++ b/packages/google-apps-chat/setup.py @@ -48,7 +48,7 @@ "proto-plus >= 1.22.3, <2.0.0", "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", "protobuf>=3.20.2,<7.0.0,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", - "google-apps-card >= 0.1.2, <1.0.0", + "google-apps-card >= 0.3.0, <1.0.0", ] extras = {} url = "https://github.com/googleapis/google-cloud-python/tree/main/packages/google-apps-chat" diff --git a/packages/google-apps-chat/testing/constraints-3.7.txt b/packages/google-apps-chat/testing/constraints-3.7.txt index ac3e925b097f..5165f9268984 100644 --- a/packages/google-apps-chat/testing/constraints-3.7.txt +++ b/packages/google-apps-chat/testing/constraints-3.7.txt @@ -10,4 +10,4 @@ google-auth==2.14.1 # Add the minimum supported version of grpcio to constraints files proto-plus==1.22.3 protobuf==3.20.2 -google-apps-card==0.1.2 +google-apps-card==0.3.0 diff --git a/packages/google-apps-chat/tests/unit/gapic/chat_v1/test_chat_service.py b/packages/google-apps-chat/tests/unit/gapic/chat_v1/test_chat_service.py index e7b6df6f7822..0c8bf01e437a 100644 --- a/packages/google-apps-chat/tests/unit/gapic/chat_v1/test_chat_service.py +++ b/packages/google-apps-chat/tests/unit/gapic/chat_v1/test_chat_service.py @@ -22014,7 +22014,11 @@ def test_create_message_rest_call_success(request_type): "header": "header_value", "widgets": [ { - "text_paragraph": {"text": "text_value"}, + "text_paragraph": { + "text": "text_value", + "max_lines": 960, + "text_syntax": 1, + }, "image": { "image_url": "image_url_value", "on_click": { @@ -22029,6 +22033,11 @@ def test_create_message_rest_call_success(request_type): "load_indicator": 1, "persist_values": True, "interaction": 1, + "required_widgets": [ + "required_widgets_value1", + "required_widgets_value2", + ], + "all_widgets_are_required": True, }, "open_link": { "url": "url_value", @@ -22037,27 +22046,41 @@ def test_create_message_rest_call_success(request_type): }, "open_dynamic_link_action": {}, "card": {}, + "overflow_menu": { + "items": [ + { + "start_icon": { + "known_icon": "known_icon_value", + "icon_url": "icon_url_value", + "material_icon": { + "name": "name_value", + "fill": True, + "weight": 648, + "grade": 515, + }, + "alt_text": "alt_text_value", + "image_type": 1, + }, + "text": "text_value", + "on_click": {}, + "disabled": True, + } + ] + }, }, "alt_text": "alt_text_value", }, "decorated_text": { - "icon": { - "known_icon": "known_icon_value", - "icon_url": "icon_url_value", - "material_icon": { - "name": "name_value", - "fill": True, - "weight": 648, - "grade": 515, - }, - "alt_text": "alt_text_value", - "image_type": 1, - }, + "icon": {}, "start_icon": {}, + "start_icon_vertical_alignment": 1, "top_label": "top_label_value", + "top_label_text": {}, "text": "text_value", + "content_text": {}, "wrap_text": True, "bottom_label": "bottom_label_value", + "bottom_label_text": {}, "on_click": {}, "button": { "text": "text_value", @@ -22071,6 +22094,7 @@ def test_create_message_rest_call_success(request_type): "on_click": {}, "disabled": True, "alt_text": "alt_text_value", + "type_": 1, }, "switch_control": { "name": "name_value", @@ -22093,6 +22117,10 @@ def test_create_message_rest_call_success(request_type): "items": [{"text": "text_value"}] }, "auto_complete_action": {}, + "validation": { + "character_limit": 1579, + "input_type": 1, + }, "placeholder_text": "placeholder_text_value", }, "selection_input": { @@ -22167,16 +22195,49 @@ def test_create_message_rest_call_success(request_type): "text_input": {}, "selection_input": {}, "date_time_picker": {}, + "chip_list": { + "layout": 1, + "chips": [ + { + "icon": {}, + "label": "label_value", + "on_click": {}, + "enabled": True, + "disabled": True, + "alt_text": "alt_text_value", + } + ], + }, + } + ], + } + ] + }, + "carousel": { + "carousel_cards": [ + { + "widgets": [ + { + "text_paragraph": {}, + "button_list": {}, + "image": {}, } ], + "footer_widgets": {}, } ] }, + "chip_list": {}, "horizontal_alignment": 1, } ], "collapsible": True, "uncollapsible_widgets_count": 2891, + "collapse_control": { + "horizontal_alignment": 1, + "expand_button": {}, + "collapse_button": {}, + }, } ], "section_divider_style": 1, @@ -22269,6 +22330,7 @@ def test_create_message_rest_call_success(request_type): "permission_settings": { "manage_members_and_groups": { "managers_allowed": True, + "assistant_managers_allowed": True, "members_allowed": True, }, "modify_space_details": {}, @@ -23140,7 +23202,11 @@ def test_update_message_rest_call_success(request_type): "header": "header_value", "widgets": [ { - "text_paragraph": {"text": "text_value"}, + "text_paragraph": { + "text": "text_value", + "max_lines": 960, + "text_syntax": 1, + }, "image": { "image_url": "image_url_value", "on_click": { @@ -23155,6 +23221,11 @@ def test_update_message_rest_call_success(request_type): "load_indicator": 1, "persist_values": True, "interaction": 1, + "required_widgets": [ + "required_widgets_value1", + "required_widgets_value2", + ], + "all_widgets_are_required": True, }, "open_link": { "url": "url_value", @@ -23163,27 +23234,41 @@ def test_update_message_rest_call_success(request_type): }, "open_dynamic_link_action": {}, "card": {}, + "overflow_menu": { + "items": [ + { + "start_icon": { + "known_icon": "known_icon_value", + "icon_url": "icon_url_value", + "material_icon": { + "name": "name_value", + "fill": True, + "weight": 648, + "grade": 515, + }, + "alt_text": "alt_text_value", + "image_type": 1, + }, + "text": "text_value", + "on_click": {}, + "disabled": True, + } + ] + }, }, "alt_text": "alt_text_value", }, "decorated_text": { - "icon": { - "known_icon": "known_icon_value", - "icon_url": "icon_url_value", - "material_icon": { - "name": "name_value", - "fill": True, - "weight": 648, - "grade": 515, - }, - "alt_text": "alt_text_value", - "image_type": 1, - }, + "icon": {}, "start_icon": {}, + "start_icon_vertical_alignment": 1, "top_label": "top_label_value", + "top_label_text": {}, "text": "text_value", + "content_text": {}, "wrap_text": True, "bottom_label": "bottom_label_value", + "bottom_label_text": {}, "on_click": {}, "button": { "text": "text_value", @@ -23197,6 +23282,7 @@ def test_update_message_rest_call_success(request_type): "on_click": {}, "disabled": True, "alt_text": "alt_text_value", + "type_": 1, }, "switch_control": { "name": "name_value", @@ -23219,6 +23305,10 @@ def test_update_message_rest_call_success(request_type): "items": [{"text": "text_value"}] }, "auto_complete_action": {}, + "validation": { + "character_limit": 1579, + "input_type": 1, + }, "placeholder_text": "placeholder_text_value", }, "selection_input": { @@ -23293,16 +23383,49 @@ def test_update_message_rest_call_success(request_type): "text_input": {}, "selection_input": {}, "date_time_picker": {}, + "chip_list": { + "layout": 1, + "chips": [ + { + "icon": {}, + "label": "label_value", + "on_click": {}, + "enabled": True, + "disabled": True, + "alt_text": "alt_text_value", + } + ], + }, + } + ], + } + ] + }, + "carousel": { + "carousel_cards": [ + { + "widgets": [ + { + "text_paragraph": {}, + "button_list": {}, + "image": {}, } ], + "footer_widgets": {}, } ] }, + "chip_list": {}, "horizontal_alignment": 1, } ], "collapsible": True, "uncollapsible_widgets_count": 2891, + "collapse_control": { + "horizontal_alignment": 1, + "expand_button": {}, + "collapse_button": {}, + }, } ], "section_divider_style": 1, @@ -23395,6 +23518,7 @@ def test_update_message_rest_call_success(request_type): "permission_settings": { "manage_members_and_groups": { "managers_allowed": True, + "assistant_managers_allowed": True, "members_allowed": True, }, "modify_space_details": {}, @@ -24453,6 +24577,7 @@ def test_create_space_rest_call_success(request_type): "permission_settings": { "manage_members_and_groups": { "managers_allowed": True, + "assistant_managers_allowed": True, "members_allowed": True, }, "modify_space_details": {}, @@ -24863,6 +24988,7 @@ def test_update_space_rest_call_success(request_type): "permission_settings": { "manage_members_and_groups": { "managers_allowed": True, + "assistant_managers_allowed": True, "members_allowed": True, }, "modify_space_details": {}, diff --git a/packages/google-cloud-common/noxfile.py b/packages/google-cloud-common/noxfile.py index 7f1f12d7e667..d8e06c8b187c 100644 --- a/packages/google-cloud-common/noxfile.py +++ b/packages/google-cloud-common/noxfile.py @@ -27,6 +27,10 @@ LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] +# Add samples to the list of directories to format if the directory exists. +if os.path.isdir("samples"): + LINT_PATHS.append("samples") + ALL_PYTHON = [ "3.7", "3.8", diff --git a/packages/google-cloud-dataplex/google/cloud/dataplex/__init__.py b/packages/google-cloud-dataplex/google/cloud/dataplex/__init__.py index c72588ce32f9..391bf1849d52 100644 --- a/packages/google-cloud-dataplex/google/cloud/dataplex/__init__.py +++ b/packages/google-cloud-dataplex/google/cloud/dataplex/__init__.py @@ -159,6 +159,10 @@ DataDiscoveryResult, DataDiscoverySpec, ) +from google.cloud.dataplex_v1.types.data_documentation import ( + DataDocumentationResult, + DataDocumentationSpec, +) from google.cloud.dataplex_v1.types.data_profile import ( DataProfileResult, DataProfileSpec, @@ -406,6 +410,8 @@ "UpdateContentRequest", "DataDiscoveryResult", "DataDiscoverySpec", + "DataDocumentationResult", + "DataDocumentationSpec", "DataProfileResult", "DataProfileSpec", "DataQualityColumnResult", diff --git a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/__init__.py b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/__init__.py index 104b6f66fc5d..570e9688b616 100644 --- a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/__init__.py +++ b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/__init__.py @@ -127,6 +127,7 @@ UpdateContentRequest, ) from .types.data_discovery import DataDiscoveryResult, DataDiscoverySpec +from .types.data_documentation import DataDocumentationResult, DataDocumentationSpec from .types.data_profile import DataProfileResult, DataProfileSpec from .types.data_quality import ( DataQualityColumnResult, @@ -308,6 +309,8 @@ "DataAttributeBinding", "DataDiscoveryResult", "DataDiscoverySpec", + "DataDocumentationResult", + "DataDocumentationSpec", "DataProfileResult", "DataProfileSpec", "DataQualityColumnResult", diff --git a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/catalog_service/async_client.py b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/catalog_service/async_client.py index 9f620c738b28..32773531b3f4 100644 --- a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/catalog_service/async_client.py +++ b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/catalog_service/async_client.py @@ -2662,7 +2662,12 @@ async def list_entries( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListEntriesAsyncPager: - r"""Lists Entries within an EntryGroup. + r"""Lists Entries within an EntryGroup. Caution: The Vertex AI, + Bigtable, Spanner, Pub/Sub, Dataform, and Dataproc Metastore + metadata that is stored in Dataplex Universal Catalog is + changing. For more information, see `Changes to metadata stored + in Dataplex Universal + Catalog `__. .. code-block:: python @@ -2787,7 +2792,12 @@ async def get_entry( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> catalog.Entry: - r"""Gets an Entry. + r"""Gets an Entry. Caution: The Vertex AI, Bigtable, Spanner, + Pub/Sub, Dataform, and Dataproc Metastore metadata that is + stored in Dataplex Universal Catalog is changing. For more + information, see `Changes to metadata stored in Dataplex + Universal + Catalog `__. .. code-block:: python @@ -2897,8 +2907,12 @@ async def lookup_entry( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> catalog.Entry: - r"""Looks up an entry by name using the permission on the - source system. + r"""Looks up an entry by name using the permission on the source + system. Caution: The Vertex AI, Bigtable, Spanner, Pub/Sub, + Dataform, and Dataproc Metastore metadata that is stored in + Dataplex Universal Catalog is changing. For more information, + see `Changes to metadata stored in Dataplex Universal + Catalog `__. .. code-block:: python diff --git a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/catalog_service/client.py b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/catalog_service/client.py index 18128a64f5b6..80b986b20f54 100644 --- a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/catalog_service/client.py +++ b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/catalog_service/client.py @@ -3161,7 +3161,12 @@ def list_entries( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> pagers.ListEntriesPager: - r"""Lists Entries within an EntryGroup. + r"""Lists Entries within an EntryGroup. Caution: The Vertex AI, + Bigtable, Spanner, Pub/Sub, Dataform, and Dataproc Metastore + metadata that is stored in Dataplex Universal Catalog is + changing. For more information, see `Changes to metadata stored + in Dataplex Universal + Catalog `__. .. code-block:: python @@ -3283,7 +3288,12 @@ def get_entry( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> catalog.Entry: - r"""Gets an Entry. + r"""Gets an Entry. Caution: The Vertex AI, Bigtable, Spanner, + Pub/Sub, Dataform, and Dataproc Metastore metadata that is + stored in Dataplex Universal Catalog is changing. For more + information, see `Changes to metadata stored in Dataplex + Universal + Catalog `__. .. code-block:: python @@ -3390,8 +3400,12 @@ def lookup_entry( timeout: Union[float, object] = gapic_v1.method.DEFAULT, metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), ) -> catalog.Entry: - r"""Looks up an entry by name using the permission on the - source system. + r"""Looks up an entry by name using the permission on the source + system. Caution: The Vertex AI, Bigtable, Spanner, Pub/Sub, + Dataform, and Dataproc Metastore metadata that is stored in + Dataplex Universal Catalog is changing. For more information, + see `Changes to metadata stored in Dataplex Universal + Catalog `__. .. code-block:: python diff --git a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/catalog_service/transports/grpc.py b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/catalog_service/transports/grpc.py index 1a31c7934664..cec2ceecae6f 100644 --- a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/catalog_service/transports/grpc.py +++ b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/catalog_service/transports/grpc.py @@ -816,7 +816,12 @@ def list_entries( ) -> Callable[[catalog.ListEntriesRequest], catalog.ListEntriesResponse]: r"""Return a callable for the list entries method over gRPC. - Lists Entries within an EntryGroup. + Lists Entries within an EntryGroup. Caution: The Vertex AI, + Bigtable, Spanner, Pub/Sub, Dataform, and Dataproc Metastore + metadata that is stored in Dataplex Universal Catalog is + changing. For more information, see `Changes to metadata stored + in Dataplex Universal + Catalog `__. Returns: Callable[[~.ListEntriesRequest], @@ -840,7 +845,12 @@ def list_entries( def get_entry(self) -> Callable[[catalog.GetEntryRequest], catalog.Entry]: r"""Return a callable for the get entry method over gRPC. - Gets an Entry. + Gets an Entry. Caution: The Vertex AI, Bigtable, Spanner, + Pub/Sub, Dataform, and Dataproc Metastore metadata that is + stored in Dataplex Universal Catalog is changing. For more + information, see `Changes to metadata stored in Dataplex + Universal + Catalog `__. Returns: Callable[[~.GetEntryRequest], @@ -864,8 +874,12 @@ def get_entry(self) -> Callable[[catalog.GetEntryRequest], catalog.Entry]: def lookup_entry(self) -> Callable[[catalog.LookupEntryRequest], catalog.Entry]: r"""Return a callable for the lookup entry method over gRPC. - Looks up an entry by name using the permission on the - source system. + Looks up an entry by name using the permission on the source + system. Caution: The Vertex AI, Bigtable, Spanner, Pub/Sub, + Dataform, and Dataproc Metastore metadata that is stored in + Dataplex Universal Catalog is changing. For more information, + see `Changes to metadata stored in Dataplex Universal + Catalog `__. Returns: Callable[[~.LookupEntryRequest], diff --git a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/catalog_service/transports/grpc_asyncio.py b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/catalog_service/transports/grpc_asyncio.py index 6a0e36f233ef..1b8104c464f2 100644 --- a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/catalog_service/transports/grpc_asyncio.py +++ b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/catalog_service/transports/grpc_asyncio.py @@ -854,7 +854,12 @@ def list_entries( ) -> Callable[[catalog.ListEntriesRequest], Awaitable[catalog.ListEntriesResponse]]: r"""Return a callable for the list entries method over gRPC. - Lists Entries within an EntryGroup. + Lists Entries within an EntryGroup. Caution: The Vertex AI, + Bigtable, Spanner, Pub/Sub, Dataform, and Dataproc Metastore + metadata that is stored in Dataplex Universal Catalog is + changing. For more information, see `Changes to metadata stored + in Dataplex Universal + Catalog `__. Returns: Callable[[~.ListEntriesRequest], @@ -880,7 +885,12 @@ def get_entry( ) -> Callable[[catalog.GetEntryRequest], Awaitable[catalog.Entry]]: r"""Return a callable for the get entry method over gRPC. - Gets an Entry. + Gets an Entry. Caution: The Vertex AI, Bigtable, Spanner, + Pub/Sub, Dataform, and Dataproc Metastore metadata that is + stored in Dataplex Universal Catalog is changing. For more + information, see `Changes to metadata stored in Dataplex + Universal + Catalog `__. Returns: Callable[[~.GetEntryRequest], @@ -906,8 +916,12 @@ def lookup_entry( ) -> Callable[[catalog.LookupEntryRequest], Awaitable[catalog.Entry]]: r"""Return a callable for the lookup entry method over gRPC. - Looks up an entry by name using the permission on the - source system. + Looks up an entry by name using the permission on the source + system. Caution: The Vertex AI, Bigtable, Spanner, Pub/Sub, + Dataform, and Dataproc Metastore metadata that is stored in + Dataplex Universal Catalog is changing. For more information, + see `Changes to metadata stored in Dataplex Universal + Catalog `__. Returns: Callable[[~.LookupEntryRequest], diff --git a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/data_scan_service/async_client.py b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/data_scan_service/async_client.py index 3bea356be2aa..d20e9f7f2368 100644 --- a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/data_scan_service/async_client.py +++ b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/data_scan_service/async_client.py @@ -57,6 +57,7 @@ from google.cloud.dataplex_v1.services.data_scan_service import pagers from google.cloud.dataplex_v1.types import ( data_discovery, + data_documentation, data_profile, data_quality, datascans, @@ -434,6 +435,12 @@ async def sample_create_data_scan(): Storage data](https://cloud.google.com/bigquery/docs/automatic-discovery). + \* Data documentation: analyzes the table details and + generates insights including descriptions and sample + SQL queries for the table. For more information, see + [Generate data insights in + BigQuery](https://cloud.google.com/bigquery/docs/data-insights). + """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have @@ -592,6 +599,12 @@ async def sample_update_data_scan(): Storage data](https://cloud.google.com/bigquery/docs/automatic-discovery). + \* Data documentation: analyzes the table details and + generates insights including descriptions and sample + SQL queries for the table. For more information, see + [Generate data insights in + BigQuery](https://cloud.google.com/bigquery/docs/data-insights). + """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have @@ -871,6 +884,12 @@ async def sample_get_data_scan(): Storage data](https://cloud.google.com/bigquery/docs/automatic-discovery). + \* Data documentation: analyzes the table details and + generates insights including descriptions and sample + SQL queries for the table. For more information, see + [Generate data insights in + BigQuery](https://cloud.google.com/bigquery/docs/data-insights). + """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have diff --git a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/data_scan_service/client.py b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/data_scan_service/client.py index ab1a281ce8e8..d66f60d087f2 100644 --- a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/data_scan_service/client.py +++ b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/data_scan_service/client.py @@ -74,6 +74,7 @@ from google.cloud.dataplex_v1.services.data_scan_service import pagers from google.cloud.dataplex_v1.types import ( data_discovery, + data_documentation, data_profile, data_quality, datascans, @@ -938,6 +939,12 @@ def sample_create_data_scan(): Storage data](https://cloud.google.com/bigquery/docs/automatic-discovery). + \* Data documentation: analyzes the table details and + generates insights including descriptions and sample + SQL queries for the table. For more information, see + [Generate data insights in + BigQuery](https://cloud.google.com/bigquery/docs/data-insights). + """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have @@ -1093,6 +1100,12 @@ def sample_update_data_scan(): Storage data](https://cloud.google.com/bigquery/docs/automatic-discovery). + \* Data documentation: analyzes the table details and + generates insights including descriptions and sample + SQL queries for the table. For more information, see + [Generate data insights in + BigQuery](https://cloud.google.com/bigquery/docs/data-insights). + """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have @@ -1366,6 +1379,12 @@ def sample_get_data_scan(): Storage data](https://cloud.google.com/bigquery/docs/automatic-discovery). + \* Data documentation: analyzes the table details and + generates insights including descriptions and sample + SQL queries for the table. For more information, see + [Generate data insights in + BigQuery](https://cloud.google.com/bigquery/docs/data-insights). + """ # Create or coerce a protobuf request object. # - Quick check: If we got a request object, we should *not* have diff --git a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/data_scan_service/transports/rest.py b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/data_scan_service/transports/rest.py index 3e9067ef25be..3cf5be664627 100644 --- a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/data_scan_service/transports/rest.py +++ b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/services/data_scan_service/transports/rest.py @@ -1425,6 +1425,11 @@ def __call__( extract and then catalog metadata. For more information, see `Discover and catalog Cloud Storage data `__. + - Data documentation: analyzes the table details and + generates insights including descriptions and sample + SQL queries for the table. For more information, see + `Generate data insights in + BigQuery `__. """ diff --git a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/__init__.py b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/__init__.py index b33e533b219c..e4594ef8f3e6 100644 --- a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/__init__.py +++ b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/__init__.py @@ -105,6 +105,7 @@ UpdateContentRequest, ) from .data_discovery import DataDiscoveryResult, DataDiscoverySpec +from .data_documentation import DataDocumentationResult, DataDocumentationSpec from .data_profile import DataProfileResult, DataProfileSpec from .data_quality import ( DataQualityColumnResult, @@ -324,6 +325,8 @@ "UpdateContentRequest", "DataDiscoveryResult", "DataDiscoverySpec", + "DataDocumentationResult", + "DataDocumentationSpec", "DataProfileResult", "DataProfileSpec", "DataQualityColumnResult", diff --git a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/catalog.py b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/catalog.py index ee7e879c9bfa..63dedd94ac1e 100644 --- a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/catalog.py +++ b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/catalog.py @@ -94,8 +94,7 @@ class EntryView(proto.Enum): GetEntryRequest. If the number of aspects exceeds 100, the first 100 will be returned. ALL (4): - Returns all aspects. If the number of aspects - exceeds 100, the first 100 will be returned. + No description available. """ ENTRY_VIEW_UNSPECIFIED = 0 BASIC = 1 @@ -161,6 +160,9 @@ class AspectType(proto.Message): client may send it on update and delete requests to ensure it has an up-to-date value before proceeding. + data_classification (google.cloud.dataplex_v1.types.AspectType.DataClassification): + Optional. Immutable. Stores data + classification of the aspect. authorization (google.cloud.dataplex_v1.types.AspectType.Authorization): Immutable. Defines the Authorization for this type. @@ -172,6 +174,19 @@ class AspectType(proto.Message): Types created from Dataplex API. """ + class DataClassification(proto.Enum): + r"""Classifies the data stored by the aspect. + + Values: + DATA_CLASSIFICATION_UNSPECIFIED (0): + Denotes that the aspect contains only + metadata. + METADATA_AND_DATA (1): + Metadata and data classification. + """ + DATA_CLASSIFICATION_UNSPECIFIED = 0 + METADATA_AND_DATA = 1 + class Authorization(proto.Message): r"""Authorization for an AspectType. @@ -454,6 +469,11 @@ class Annotations(proto.Message): proto.STRING, number=8, ) + data_classification: DataClassification = proto.Field( + proto.ENUM, + number=9, + enum=DataClassification, + ) authorization: Authorization = proto.Field( proto.MESSAGE, number=52, @@ -2553,14 +2573,13 @@ class ImportJobScope(proto.Message): Attributes: entry_groups (MutableSequence[str]): - Required. The entry group that is in scope for the import - job, specified as a relative resource name in the format + Required. The entry groups that are in scope for the import + job, specified as relative resource names in the format ``projects/{project_number_or_id}/locations/{location_id}/entryGroups/{entry_group_id}``. Only entries and aspects that belong to the specified entry - group are affected by the job. + groups are affected by the job. - Must contain exactly one element. The entry group and the - job must be in the same location. + The entry groups and the job must be in the same location. entry_types (MutableSequence[str]): Required. The entry types that are in scope for the import job, specified as relative resource names in the format diff --git a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/cmek.py b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/cmek.py index 77f2e003e2ee..208fb7fafb35 100644 --- a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/cmek.py +++ b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/cmek.py @@ -65,6 +65,9 @@ class EncryptionConfig(proto.Message): failure_details (google.cloud.dataplex_v1.types.EncryptionConfig.FailureDetails): Output only. Details of the failure if anything related to Cmek db fails. + enable_metastore_encryption (bool): + Optional. Represent the state of CMEK opt-in + for metastore. """ class EncryptionState(proto.Enum): @@ -163,6 +166,10 @@ class ErrorCode(proto.Enum): number=7, message=FailureDetails, ) + enable_metastore_encryption: bool = proto.Field( + proto.BOOL, + number=8, + ) class CreateEncryptionConfigRequest(proto.Message): diff --git a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/data_documentation.py b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/data_documentation.py new file mode 100644 index 000000000000..6a1f850aec5d --- /dev/null +++ b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/data_documentation.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.dataplex.v1", + manifest={ + "DataDocumentationSpec", + "DataDocumentationResult", + }, +) + + +class DataDocumentationSpec(proto.Message): + r"""DataDocumentation scan related spec.""" + + +class DataDocumentationResult(proto.Message): + r"""The output of a DataDocumentation scan. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + table_result (google.cloud.dataplex_v1.types.DataDocumentationResult.TableResult): + Output only. Table result for insights. + + This field is a member of `oneof`_ ``result``. + """ + + class TableResult(proto.Message): + r"""Generated metadata about the table. + + Attributes: + name (str): + Output only. The service-qualified full resource name of the + cloud resource. Ex: + //bigquery.googleapis.com/projects/PROJECT_ID/datasets/DATASET_ID/tables/TABLE_ID + overview (str): + Output only. Generated description of the + table. + schema (google.cloud.dataplex_v1.types.DataDocumentationResult.Schema): + Output only. Schema of the table with + generated metadata of the columns in the schema. + queries (MutableSequence[google.cloud.dataplex_v1.types.DataDocumentationResult.Query]): + Output only. Sample SQL queries for the + table. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + overview: str = proto.Field( + proto.STRING, + number=2, + ) + schema: "DataDocumentationResult.Schema" = proto.Field( + proto.MESSAGE, + number=3, + message="DataDocumentationResult.Schema", + ) + queries: MutableSequence["DataDocumentationResult.Query"] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message="DataDocumentationResult.Query", + ) + + class Query(proto.Message): + r"""A sample SQL query in data documentation. + + Attributes: + sql (str): + Output only. The SQL query string which can + be executed. + description (str): + Output only. The description for the query. + """ + + sql: str = proto.Field( + proto.STRING, + number=1, + ) + description: str = proto.Field( + proto.STRING, + number=2, + ) + + class Schema(proto.Message): + r"""Schema of the table with generated metadata of columns. + + Attributes: + fields (MutableSequence[google.cloud.dataplex_v1.types.DataDocumentationResult.Field]): + Output only. The list of columns. + """ + + fields: MutableSequence["DataDocumentationResult.Field"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="DataDocumentationResult.Field", + ) + + class Field(proto.Message): + r"""Column of a table with generated metadata and nested fields. + + Attributes: + name (str): + Output only. The name of the column. + description (str): + Output only. Generated description for + columns and fields. + fields (MutableSequence[google.cloud.dataplex_v1.types.DataDocumentationResult.Field]): + Output only. Nested fields. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + description: str = proto.Field( + proto.STRING, + number=2, + ) + fields: MutableSequence["DataDocumentationResult.Field"] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message="DataDocumentationResult.Field", + ) + + table_result: TableResult = proto.Field( + proto.MESSAGE, + number=8, + oneof="result", + message=TableResult, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/data_quality.py b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/data_quality.py index 23dc6dea5c1f..0a4dfae85e65 100644 --- a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/data_quality.py +++ b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/data_quality.py @@ -260,6 +260,9 @@ class DataQualityResult(proto.Message): Output only. The status of publishing the data scan as Dataplex Universal Catalog metadata. + anomaly_detection_generated_assets (google.cloud.dataplex_v1.types.DataQualityResult.AnomalyDetectionGeneratedAssets): + Output only. The generated assets for anomaly + detection. """ class PostScanActionsResult(proto.Message): @@ -320,6 +323,44 @@ class State(proto.Enum): message="DataQualityResult.PostScanActionsResult.BigQueryExportResult", ) + class AnomalyDetectionGeneratedAssets(proto.Message): + r"""The assets generated by Anomaly Detection Data Scan. + + Attributes: + result_table (str): + Output only. The result table for anomaly detection. Format: + PROJECT_ID.DATASET_ID.TABLE_ID If the result table is set at + AnomalyDetectionAssets, the result table here would be the + same as the one set in the + AnomalyDetectionAssets.result_table. + data_intermediate_table (str): + Output only. The intermediate table for data anomaly + detection. Format: PROJECT_ID.DATASET_ID.TABLE_ID + freshness_intermediate_table (str): + Output only. The intermediate table for freshness anomaly + detection. Format: PROJECT_ID.DATASET_ID.TABLE_ID + volume_intermediate_table (str): + Output only. The intermediate table for volume anomaly + detection. Format: PROJECT_ID.DATASET_ID.TABLE_ID + """ + + result_table: str = proto.Field( + proto.STRING, + number=1, + ) + data_intermediate_table: str = proto.Field( + proto.STRING, + number=2, + ) + freshness_intermediate_table: str = proto.Field( + proto.STRING, + number=3, + ) + volume_intermediate_table: str = proto.Field( + proto.STRING, + number=4, + ) + passed: bool = proto.Field( proto.BOOL, number=5, @@ -365,6 +406,11 @@ class State(proto.Enum): message=datascans_common.DataScanCatalogPublishingStatus, ) ) + anomaly_detection_generated_assets: AnomalyDetectionGeneratedAssets = proto.Field( + proto.MESSAGE, + number=12, + message=AnomalyDetectionGeneratedAssets, + ) class DataQualityRuleResult(proto.Message): diff --git a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/datascans.py b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/datascans.py index aa370fd2abb8..be3020f4d10f 100644 --- a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/datascans.py +++ b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/datascans.py @@ -23,6 +23,7 @@ from google.cloud.dataplex_v1.types import ( data_discovery, + data_documentation, data_profile, data_quality, processing, @@ -64,11 +65,14 @@ class DataScanType(proto.Enum): Data profile scan. DATA_DISCOVERY (3): Data discovery scan. + DATA_DOCUMENTATION (4): + Data documentation scan. """ DATA_SCAN_TYPE_UNSPECIFIED = 0 DATA_QUALITY = 1 DATA_PROFILE = 2 DATA_DISCOVERY = 3 + DATA_DOCUMENTATION = 4 class CreateDataScanRequest(proto.Message): @@ -518,6 +522,10 @@ class DataScan(proto.Message): then catalog metadata. For more information, see `Discover and catalog Cloud Storage data `__. + - Data documentation: analyzes the table details and generates + insights including descriptions and sample SQL queries for the + table. For more information, see `Generate data insights in + BigQuery `__. This message has `oneof`_ fields (mutually exclusive fields). For each oneof, at most one member field can be set at the same time. @@ -580,6 +588,10 @@ class DataScan(proto.Message): data_discovery_spec (google.cloud.dataplex_v1.types.DataDiscoverySpec): Settings for a data discovery scan. + This field is a member of `oneof`_ ``spec``. + data_documentation_spec (google.cloud.dataplex_v1.types.DataDocumentationSpec): + Settings for a data documentation scan. + This field is a member of `oneof`_ ``spec``. data_quality_result (google.cloud.dataplex_v1.types.DataQualityResult): Output only. The result of a data quality @@ -595,6 +607,11 @@ class DataScan(proto.Message): Output only. The result of a data discovery scan. + This field is a member of `oneof`_ ``result``. + data_documentation_result (google.cloud.dataplex_v1.types.DataDocumentationResult): + Output only. The result of a data + documentation scan. + This field is a member of `oneof`_ ``result``. """ @@ -738,6 +755,12 @@ class ExecutionStatus(proto.Message): oneof="spec", message=data_discovery.DataDiscoverySpec, ) + data_documentation_spec: data_documentation.DataDocumentationSpec = proto.Field( + proto.MESSAGE, + number=103, + oneof="spec", + message=data_documentation.DataDocumentationSpec, + ) data_quality_result: data_quality.DataQualityResult = proto.Field( proto.MESSAGE, number=200, @@ -756,6 +779,12 @@ class ExecutionStatus(proto.Message): oneof="result", message=data_discovery.DataDiscoveryResult, ) + data_documentation_result: data_documentation.DataDocumentationResult = proto.Field( + proto.MESSAGE, + number=203, + oneof="result", + message=data_documentation.DataDocumentationResult, + ) class DataScanJob(proto.Message): @@ -810,6 +839,11 @@ class DataScanJob(proto.Message): Output only. Settings for a data discovery scan. + This field is a member of `oneof`_ ``spec``. + data_documentation_spec (google.cloud.dataplex_v1.types.DataDocumentationSpec): + Output only. Settings for a data + documentation scan. + This field is a member of `oneof`_ ``spec``. data_quality_result (google.cloud.dataplex_v1.types.DataQualityResult): Output only. The result of a data quality @@ -825,6 +859,11 @@ class DataScanJob(proto.Message): Output only. The result of a data discovery scan. + This field is a member of `oneof`_ ``result``. + data_documentation_result (google.cloud.dataplex_v1.types.DataDocumentationResult): + Output only. The result of a data + documentation scan. + This field is a member of `oneof`_ ``result``. """ @@ -912,6 +951,12 @@ class State(proto.Enum): oneof="spec", message=data_discovery.DataDiscoverySpec, ) + data_documentation_spec: data_documentation.DataDocumentationSpec = proto.Field( + proto.MESSAGE, + number=103, + oneof="spec", + message=data_documentation.DataDocumentationSpec, + ) data_quality_result: data_quality.DataQualityResult = proto.Field( proto.MESSAGE, number=200, @@ -930,6 +975,12 @@ class State(proto.Enum): oneof="result", message=data_discovery.DataDiscoveryResult, ) + data_documentation_result: data_documentation.DataDocumentationResult = proto.Field( + proto.MESSAGE, + number=203, + oneof="result", + message=data_documentation.DataDocumentationResult, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/processing.py b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/processing.py index cbf390d581b3..3c638c416fcc 100644 --- a/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/processing.py +++ b/packages/google-cloud-dataplex/google/cloud/dataplex_v1/types/processing.py @@ -116,7 +116,8 @@ class DataSource(proto.Message): Format: //storage.googleapis.com/projects/PROJECT_ID/buckets/BUCKET_ID or BigQuery table of type "TABLE" for - DataProfileScan/DataQualityScan Format: + DataProfileScan/DataQualityScan/DataDocumentationScan + Format: //bigquery.googleapis.com/projects/PROJECT_ID/datasets/DATASET_ID/tables/TABLE_ID This field is a member of `oneof`_ ``source``. diff --git a/packages/google-cloud-dataplex/noxfile.py b/packages/google-cloud-dataplex/noxfile.py index 43f09fef2689..53f1df180441 100644 --- a/packages/google-cloud-dataplex/noxfile.py +++ b/packages/google-cloud-dataplex/noxfile.py @@ -27,6 +27,10 @@ LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] +# Add samples to the list of directories to format if the directory exists. +if os.path.isdir("samples"): + LINT_PATHS.append("samples") + ALL_PYTHON = [ "3.7", "3.8", diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_async.py index c87894b42634..00347c433f5b 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_async.py @@ -54,4 +54,5 @@ async def sample_create_glossary(): # Handle the response print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_CreateGlossary_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_category_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_category_async.py index 02835539a9b5..4da689ede395 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_category_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_category_async.py @@ -54,4 +54,5 @@ async def sample_create_glossary_category(): # Handle the response print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_CreateGlossaryCategory_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_category_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_category_sync.py index 2a3ed96a2236..41b5f9e7d0af 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_category_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_category_sync.py @@ -54,4 +54,5 @@ def sample_create_glossary_category(): # Handle the response print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_CreateGlossaryCategory_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_sync.py index fcbc1d2bdeae..6bd49161018e 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_sync.py @@ -54,4 +54,5 @@ def sample_create_glossary(): # Handle the response print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_CreateGlossary_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_term_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_term_async.py index 08851757a5be..e9f1a0a3e805 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_term_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_term_async.py @@ -54,4 +54,5 @@ async def sample_create_glossary_term(): # Handle the response print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_CreateGlossaryTerm_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_term_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_term_sync.py index 9987138e7c68..3bddcd1c67d8 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_term_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_create_glossary_term_sync.py @@ -54,4 +54,5 @@ def sample_create_glossary_term(): # Handle the response print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_CreateGlossaryTerm_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_delete_glossary_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_delete_glossary_async.py index 770ba6a5e13f..aa432a597b5e 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_delete_glossary_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_delete_glossary_async.py @@ -53,4 +53,5 @@ async def sample_delete_glossary(): # Handle the response print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_DeleteGlossary_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_delete_glossary_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_delete_glossary_sync.py index ce878bcc195e..ef9f93ae5bed 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_delete_glossary_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_delete_glossary_sync.py @@ -53,4 +53,5 @@ def sample_delete_glossary(): # Handle the response print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_DeleteGlossary_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_async.py index b46e94009514..6bed0fd47c98 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_async.py @@ -49,4 +49,5 @@ async def sample_get_glossary(): # Handle the response print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_GetGlossary_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_category_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_category_async.py index 7524e741a51d..ee53cfebb6da 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_category_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_category_async.py @@ -49,4 +49,5 @@ async def sample_get_glossary_category(): # Handle the response print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_GetGlossaryCategory_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_category_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_category_sync.py index 43e3d9ec99a5..cf7958672020 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_category_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_category_sync.py @@ -49,4 +49,5 @@ def sample_get_glossary_category(): # Handle the response print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_GetGlossaryCategory_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_sync.py index 943a5534d01a..417a6fa6eca8 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_sync.py @@ -49,4 +49,5 @@ def sample_get_glossary(): # Handle the response print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_GetGlossary_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_term_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_term_async.py index baf885229bbc..942fafb01103 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_term_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_term_async.py @@ -49,4 +49,5 @@ async def sample_get_glossary_term(): # Handle the response print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_GetGlossaryTerm_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_term_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_term_sync.py index 3b2368612e89..c730be76f4a1 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_term_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_get_glossary_term_sync.py @@ -49,4 +49,5 @@ def sample_get_glossary_term(): # Handle the response print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_GetGlossaryTerm_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossaries_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossaries_async.py index d9dbd0f0767c..89598e261de4 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossaries_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossaries_async.py @@ -50,4 +50,5 @@ async def sample_list_glossaries(): async for response in page_result: print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_ListGlossaries_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossaries_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossaries_sync.py index 1b2469dcf0b9..a362e98f11da 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossaries_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossaries_sync.py @@ -50,4 +50,5 @@ def sample_list_glossaries(): for response in page_result: print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_ListGlossaries_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossary_categories_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossary_categories_async.py index 14d77cb5f9a3..c746717f3100 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossary_categories_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossary_categories_async.py @@ -50,4 +50,5 @@ async def sample_list_glossary_categories(): async for response in page_result: print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_ListGlossaryCategories_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossary_categories_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossary_categories_sync.py index 357b89a4a77c..1b374248b0fe 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossary_categories_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossary_categories_sync.py @@ -50,4 +50,5 @@ def sample_list_glossary_categories(): for response in page_result: print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_ListGlossaryCategories_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossary_terms_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossary_terms_async.py index d3a9df2e788d..e4a002d0f6ce 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossary_terms_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossary_terms_async.py @@ -50,4 +50,5 @@ async def sample_list_glossary_terms(): async for response in page_result: print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_ListGlossaryTerms_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossary_terms_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossary_terms_sync.py index 7f3d1a00bc6c..41d606b4cf55 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossary_terms_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_list_glossary_terms_sync.py @@ -50,4 +50,5 @@ def sample_list_glossary_terms(): for response in page_result: print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_ListGlossaryTerms_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_async.py index 21cc26ce8a41..656001d962c3 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_async.py @@ -39,8 +39,7 @@ async def sample_update_glossary(): client = dataplex_v1.BusinessGlossaryServiceAsyncClient() # Initialize request argument(s) - request = dataplex_v1.UpdateGlossaryRequest( - ) + request = dataplex_v1.UpdateGlossaryRequest() # Make the request operation = client.update_glossary(request=request) @@ -52,4 +51,5 @@ async def sample_update_glossary(): # Handle the response print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_UpdateGlossary_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_category_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_category_async.py index bc9f3931ebeb..415dac6592bf 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_category_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_category_async.py @@ -52,4 +52,5 @@ async def sample_update_glossary_category(): # Handle the response print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_UpdateGlossaryCategory_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_category_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_category_sync.py index 27c16af104b4..0c40c18aa355 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_category_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_category_sync.py @@ -52,4 +52,5 @@ def sample_update_glossary_category(): # Handle the response print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_UpdateGlossaryCategory_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_sync.py index 9e5cda83589d..9a42ce0b5290 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_sync.py @@ -39,8 +39,7 @@ def sample_update_glossary(): client = dataplex_v1.BusinessGlossaryServiceClient() # Initialize request argument(s) - request = dataplex_v1.UpdateGlossaryRequest( - ) + request = dataplex_v1.UpdateGlossaryRequest() # Make the request operation = client.update_glossary(request=request) @@ -52,4 +51,5 @@ def sample_update_glossary(): # Handle the response print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_UpdateGlossary_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_term_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_term_async.py index f1c0183067c4..ad3d2415b8e1 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_term_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_term_async.py @@ -52,4 +52,5 @@ async def sample_update_glossary_term(): # Handle the response print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_UpdateGlossaryTerm_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_term_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_term_sync.py index f162ab6e6cd5..d67a2692878c 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_term_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_business_glossary_service_update_glossary_term_sync.py @@ -52,4 +52,5 @@ def sample_update_glossary_term(): # Handle the response print(response) + # [END dataplex_v1_generated_BusinessGlossaryService_UpdateGlossaryTerm_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_aspect_type_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_aspect_type_async.py index fcdb536becdd..bbcd546a5508 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_aspect_type_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_aspect_type_async.py @@ -59,4 +59,5 @@ async def sample_create_aspect_type(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_CreateAspectType_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_aspect_type_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_aspect_type_sync.py index ebd0cd697960..4fc785f7fd9b 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_aspect_type_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_aspect_type_sync.py @@ -59,4 +59,5 @@ def sample_create_aspect_type(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_CreateAspectType_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_async.py index 307179eca305..d60e2df6dd88 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_async.py @@ -54,4 +54,5 @@ async def sample_create_entry(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_CreateEntry_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_group_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_group_async.py index 10156ffe9405..33cd60065607 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_group_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_group_async.py @@ -54,4 +54,5 @@ async def sample_create_entry_group(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_CreateEntryGroup_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_group_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_group_sync.py index e6c5c4b0c6e0..d9481aecaf74 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_group_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_group_sync.py @@ -54,4 +54,5 @@ def sample_create_entry_group(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_CreateEntryGroup_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_link_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_link_async.py index 11fdd293d63e..4ae31dc50d90 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_link_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_link_async.py @@ -56,4 +56,5 @@ async def sample_create_entry_link(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_CreateEntryLink_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_link_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_link_sync.py index 545fc9510ac8..d5d986625f4a 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_link_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_link_sync.py @@ -56,4 +56,5 @@ def sample_create_entry_link(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_CreateEntryLink_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_sync.py index 9d08ecbcc807..ea9eb834f4e5 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_sync.py @@ -54,4 +54,5 @@ def sample_create_entry(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_CreateEntry_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_type_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_type_async.py index c8c93d0810d9..c7ed952a6b95 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_type_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_type_async.py @@ -54,4 +54,5 @@ async def sample_create_entry_type(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_CreateEntryType_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_type_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_type_sync.py index 1f07e18303ec..6be3aed5c964 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_type_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_entry_type_sync.py @@ -54,4 +54,5 @@ def sample_create_entry_type(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_CreateEntryType_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_metadata_job_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_metadata_job_async.py index 176dc8f6b21a..df1322c77808 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_metadata_job_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_metadata_job_async.py @@ -40,8 +40,14 @@ async def sample_create_metadata_job(): # Initialize request argument(s) metadata_job = dataplex_v1.MetadataJob() - metadata_job.import_spec.scope.entry_groups = ['entry_groups_value1', 'entry_groups_value2'] - metadata_job.import_spec.scope.entry_types = ['entry_types_value1', 'entry_types_value2'] + metadata_job.import_spec.scope.entry_groups = [ + "entry_groups_value1", + "entry_groups_value2", + ] + metadata_job.import_spec.scope.entry_types = [ + "entry_types_value1", + "entry_types_value2", + ] metadata_job.import_spec.entry_sync_mode = "NONE" metadata_job.import_spec.aspect_sync_mode = "NONE" metadata_job.type_ = "EXPORT" @@ -61,4 +67,5 @@ async def sample_create_metadata_job(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_CreateMetadataJob_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_metadata_job_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_metadata_job_sync.py index fffa3dca81b3..95e84722c29d 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_metadata_job_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_create_metadata_job_sync.py @@ -40,8 +40,14 @@ def sample_create_metadata_job(): # Initialize request argument(s) metadata_job = dataplex_v1.MetadataJob() - metadata_job.import_spec.scope.entry_groups = ['entry_groups_value1', 'entry_groups_value2'] - metadata_job.import_spec.scope.entry_types = ['entry_types_value1', 'entry_types_value2'] + metadata_job.import_spec.scope.entry_groups = [ + "entry_groups_value1", + "entry_groups_value2", + ] + metadata_job.import_spec.scope.entry_types = [ + "entry_types_value1", + "entry_types_value2", + ] metadata_job.import_spec.entry_sync_mode = "NONE" metadata_job.import_spec.aspect_sync_mode = "NONE" metadata_job.type_ = "EXPORT" @@ -61,4 +67,5 @@ def sample_create_metadata_job(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_CreateMetadataJob_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_aspect_type_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_aspect_type_async.py index 977d70c886fe..ff461c1547e2 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_aspect_type_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_aspect_type_async.py @@ -53,4 +53,5 @@ async def sample_delete_aspect_type(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_DeleteAspectType_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_aspect_type_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_aspect_type_sync.py index 7bb600cd72a3..4e112c52e26e 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_aspect_type_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_aspect_type_sync.py @@ -53,4 +53,5 @@ def sample_delete_aspect_type(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_DeleteAspectType_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_async.py index 7f75da02f2a5..3ba43d594d00 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_async.py @@ -49,4 +49,5 @@ async def sample_delete_entry(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_DeleteEntry_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_group_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_group_async.py index 0efb92609a71..72eb46700061 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_group_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_group_async.py @@ -53,4 +53,5 @@ async def sample_delete_entry_group(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_DeleteEntryGroup_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_group_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_group_sync.py index cf187e0a1e01..a7cb5cf6d2d7 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_group_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_group_sync.py @@ -53,4 +53,5 @@ def sample_delete_entry_group(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_DeleteEntryGroup_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_link_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_link_async.py index 5f6e273420d5..42a978e4947d 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_link_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_link_async.py @@ -49,4 +49,5 @@ async def sample_delete_entry_link(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_DeleteEntryLink_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_link_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_link_sync.py index 9fe8fd9e84e0..78094c2e0e30 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_link_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_link_sync.py @@ -49,4 +49,5 @@ def sample_delete_entry_link(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_DeleteEntryLink_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_sync.py index 827f2dfb7f63..cd50a9dbba20 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_sync.py @@ -49,4 +49,5 @@ def sample_delete_entry(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_DeleteEntry_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_type_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_type_async.py index 8a877e0d7180..8b180302da22 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_type_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_type_async.py @@ -53,4 +53,5 @@ async def sample_delete_entry_type(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_DeleteEntryType_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_type_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_type_sync.py index eaed87a6d471..2b233709f263 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_type_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_delete_entry_type_sync.py @@ -53,4 +53,5 @@ def sample_delete_entry_type(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_DeleteEntryType_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_aspect_type_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_aspect_type_async.py index 3c98341d85fd..f4ea8d2240ee 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_aspect_type_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_aspect_type_async.py @@ -49,4 +49,5 @@ async def sample_get_aspect_type(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_GetAspectType_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_aspect_type_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_aspect_type_sync.py index 238e178abf2e..751dc3d84c97 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_aspect_type_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_aspect_type_sync.py @@ -49,4 +49,5 @@ def sample_get_aspect_type(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_GetAspectType_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_async.py index ec327f90378e..eb88db2ce9b8 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_async.py @@ -49,4 +49,5 @@ async def sample_get_entry(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_GetEntry_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_group_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_group_async.py index 6c047da8ee7a..e4853a53c2fd 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_group_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_group_async.py @@ -49,4 +49,5 @@ async def sample_get_entry_group(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_GetEntryGroup_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_group_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_group_sync.py index 6d552d21d845..6df1175cb8d9 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_group_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_group_sync.py @@ -49,4 +49,5 @@ def sample_get_entry_group(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_GetEntryGroup_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_link_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_link_async.py index c60929bae482..7eb37bca8907 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_link_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_link_async.py @@ -49,4 +49,5 @@ async def sample_get_entry_link(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_GetEntryLink_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_link_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_link_sync.py index 5c090b4900f2..2e3e1e0a13a6 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_link_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_link_sync.py @@ -49,4 +49,5 @@ def sample_get_entry_link(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_GetEntryLink_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_sync.py index bd0bf1f995b0..0494241ccb81 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_sync.py @@ -49,4 +49,5 @@ def sample_get_entry(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_GetEntry_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_type_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_type_async.py index 4a57ddcf1cf3..c29bf3fd4c37 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_type_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_type_async.py @@ -49,4 +49,5 @@ async def sample_get_entry_type(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_GetEntryType_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_type_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_type_sync.py index 27060439c400..65ddc0499765 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_type_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_entry_type_sync.py @@ -49,4 +49,5 @@ def sample_get_entry_type(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_GetEntryType_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_metadata_job_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_metadata_job_async.py index d2da4af3ae6c..1f5f31c5203f 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_metadata_job_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_metadata_job_async.py @@ -49,4 +49,5 @@ async def sample_get_metadata_job(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_GetMetadataJob_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_metadata_job_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_metadata_job_sync.py index 40fcab33f820..4dc647c26d9e 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_metadata_job_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_get_metadata_job_sync.py @@ -49,4 +49,5 @@ def sample_get_metadata_job(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_GetMetadataJob_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_aspect_types_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_aspect_types_async.py index 8b9ae3b16b14..1ab4598ff1fa 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_aspect_types_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_aspect_types_async.py @@ -50,4 +50,5 @@ async def sample_list_aspect_types(): async for response in page_result: print(response) + # [END dataplex_v1_generated_CatalogService_ListAspectTypes_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_aspect_types_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_aspect_types_sync.py index 7f9ca88942bd..ee7c072b46b5 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_aspect_types_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_aspect_types_sync.py @@ -50,4 +50,5 @@ def sample_list_aspect_types(): for response in page_result: print(response) + # [END dataplex_v1_generated_CatalogService_ListAspectTypes_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entries_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entries_async.py index 7562629a5995..d83589583a9b 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entries_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entries_async.py @@ -50,4 +50,5 @@ async def sample_list_entries(): async for response in page_result: print(response) + # [END dataplex_v1_generated_CatalogService_ListEntries_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entries_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entries_sync.py index c7a9e8bceb7c..833662ab64f0 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entries_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entries_sync.py @@ -50,4 +50,5 @@ def sample_list_entries(): for response in page_result: print(response) + # [END dataplex_v1_generated_CatalogService_ListEntries_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entry_groups_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entry_groups_async.py index e414df47c3a4..09568ec0cb74 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entry_groups_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entry_groups_async.py @@ -50,4 +50,5 @@ async def sample_list_entry_groups(): async for response in page_result: print(response) + # [END dataplex_v1_generated_CatalogService_ListEntryGroups_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entry_groups_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entry_groups_sync.py index eb480ab9c3d1..cbef95d6b8de 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entry_groups_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entry_groups_sync.py @@ -50,4 +50,5 @@ def sample_list_entry_groups(): for response in page_result: print(response) + # [END dataplex_v1_generated_CatalogService_ListEntryGroups_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entry_types_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entry_types_async.py index e6bcb19bc98e..50d33a0f5ae8 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entry_types_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entry_types_async.py @@ -50,4 +50,5 @@ async def sample_list_entry_types(): async for response in page_result: print(response) + # [END dataplex_v1_generated_CatalogService_ListEntryTypes_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entry_types_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entry_types_sync.py index 9cc615ff9dd5..a535f7a6120e 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entry_types_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_entry_types_sync.py @@ -50,4 +50,5 @@ def sample_list_entry_types(): for response in page_result: print(response) + # [END dataplex_v1_generated_CatalogService_ListEntryTypes_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_metadata_jobs_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_metadata_jobs_async.py index 9a08c5162a08..c8b2a55aa654 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_metadata_jobs_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_metadata_jobs_async.py @@ -50,4 +50,5 @@ async def sample_list_metadata_jobs(): async for response in page_result: print(response) + # [END dataplex_v1_generated_CatalogService_ListMetadataJobs_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_metadata_jobs_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_metadata_jobs_sync.py index 36fd4a81d24c..668d59a01b8e 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_metadata_jobs_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_list_metadata_jobs_sync.py @@ -50,4 +50,5 @@ def sample_list_metadata_jobs(): for response in page_result: print(response) + # [END dataplex_v1_generated_CatalogService_ListMetadataJobs_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_lookup_entry_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_lookup_entry_async.py index 9aacffaf9a30..ae89884b8859 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_lookup_entry_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_lookup_entry_async.py @@ -50,4 +50,5 @@ async def sample_lookup_entry(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_LookupEntry_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_lookup_entry_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_lookup_entry_sync.py index f79f5f04126e..9f91257c569e 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_lookup_entry_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_lookup_entry_sync.py @@ -50,4 +50,5 @@ def sample_lookup_entry(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_LookupEntry_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_search_entries_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_search_entries_async.py index ba04f5e078a4..0ae2bc6544e5 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_search_entries_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_search_entries_async.py @@ -51,4 +51,5 @@ async def sample_search_entries(): async for response in page_result: print(response) + # [END dataplex_v1_generated_CatalogService_SearchEntries_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_search_entries_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_search_entries_sync.py index 04b5643e21c6..42fd982acd66 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_search_entries_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_search_entries_sync.py @@ -51,4 +51,5 @@ def sample_search_entries(): for response in page_result: print(response) + # [END dataplex_v1_generated_CatalogService_SearchEntries_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_aspect_type_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_aspect_type_async.py index fdaad89c0129..6c06f479adde 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_aspect_type_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_aspect_type_async.py @@ -57,4 +57,5 @@ async def sample_update_aspect_type(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_UpdateAspectType_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_aspect_type_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_aspect_type_sync.py index 79049dd35006..e45a95c6a00b 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_aspect_type_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_aspect_type_sync.py @@ -57,4 +57,5 @@ def sample_update_aspect_type(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_UpdateAspectType_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_async.py index b1acbea5b5db..d0aaf77a15a6 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_async.py @@ -52,4 +52,5 @@ async def sample_update_entry(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_UpdateEntry_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_group_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_group_async.py index c084f241abb9..3049334974f2 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_group_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_group_async.py @@ -39,8 +39,7 @@ async def sample_update_entry_group(): client = dataplex_v1.CatalogServiceAsyncClient() # Initialize request argument(s) - request = dataplex_v1.UpdateEntryGroupRequest( - ) + request = dataplex_v1.UpdateEntryGroupRequest() # Make the request operation = client.update_entry_group(request=request) @@ -52,4 +51,5 @@ async def sample_update_entry_group(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_UpdateEntryGroup_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_group_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_group_sync.py index 82aa81ae58fd..3e663c02665a 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_group_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_group_sync.py @@ -39,8 +39,7 @@ def sample_update_entry_group(): client = dataplex_v1.CatalogServiceClient() # Initialize request argument(s) - request = dataplex_v1.UpdateEntryGroupRequest( - ) + request = dataplex_v1.UpdateEntryGroupRequest() # Make the request operation = client.update_entry_group(request=request) @@ -52,4 +51,5 @@ def sample_update_entry_group(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_UpdateEntryGroup_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_sync.py index 4d38a5ac7833..7f85e1a86e7a 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_sync.py @@ -52,4 +52,5 @@ def sample_update_entry(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_UpdateEntry_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_type_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_type_async.py index f19a55e6b0e6..c9699208e3cb 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_type_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_type_async.py @@ -39,8 +39,7 @@ async def sample_update_entry_type(): client = dataplex_v1.CatalogServiceAsyncClient() # Initialize request argument(s) - request = dataplex_v1.UpdateEntryTypeRequest( - ) + request = dataplex_v1.UpdateEntryTypeRequest() # Make the request operation = client.update_entry_type(request=request) @@ -52,4 +51,5 @@ async def sample_update_entry_type(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_UpdateEntryType_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_type_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_type_sync.py index 47bd13e333ae..950e971d7e77 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_type_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_catalog_service_update_entry_type_sync.py @@ -39,8 +39,7 @@ def sample_update_entry_type(): client = dataplex_v1.CatalogServiceClient() # Initialize request argument(s) - request = dataplex_v1.UpdateEntryTypeRequest( - ) + request = dataplex_v1.UpdateEntryTypeRequest() # Make the request operation = client.update_entry_type(request=request) @@ -52,4 +51,5 @@ def sample_update_entry_type(): # Handle the response print(response) + # [END dataplex_v1_generated_CatalogService_UpdateEntryType_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_create_encryption_config_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_create_encryption_config_async.py index 4cc2c823341a..629a74bfd25a 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_create_encryption_config_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_create_encryption_config_async.py @@ -54,4 +54,5 @@ async def sample_create_encryption_config(): # Handle the response print(response) + # [END dataplex_v1_generated_CmekService_CreateEncryptionConfig_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_create_encryption_config_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_create_encryption_config_sync.py index c170b0a8d37c..f341ef68735b 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_create_encryption_config_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_create_encryption_config_sync.py @@ -54,4 +54,5 @@ def sample_create_encryption_config(): # Handle the response print(response) + # [END dataplex_v1_generated_CmekService_CreateEncryptionConfig_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_delete_encryption_config_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_delete_encryption_config_async.py index bc483ea781a9..71c2d412fcb8 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_delete_encryption_config_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_delete_encryption_config_async.py @@ -53,4 +53,5 @@ async def sample_delete_encryption_config(): # Handle the response print(response) + # [END dataplex_v1_generated_CmekService_DeleteEncryptionConfig_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_delete_encryption_config_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_delete_encryption_config_sync.py index b79392c229ea..0b820227cf3d 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_delete_encryption_config_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_delete_encryption_config_sync.py @@ -53,4 +53,5 @@ def sample_delete_encryption_config(): # Handle the response print(response) + # [END dataplex_v1_generated_CmekService_DeleteEncryptionConfig_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_get_encryption_config_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_get_encryption_config_async.py index 6c00b9ee027e..310860c37bfd 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_get_encryption_config_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_get_encryption_config_async.py @@ -49,4 +49,5 @@ async def sample_get_encryption_config(): # Handle the response print(response) + # [END dataplex_v1_generated_CmekService_GetEncryptionConfig_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_get_encryption_config_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_get_encryption_config_sync.py index 837fdfb77220..343f67e490b6 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_get_encryption_config_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_get_encryption_config_sync.py @@ -49,4 +49,5 @@ def sample_get_encryption_config(): # Handle the response print(response) + # [END dataplex_v1_generated_CmekService_GetEncryptionConfig_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_list_encryption_configs_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_list_encryption_configs_async.py index 0af63d57396e..05120b93b36b 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_list_encryption_configs_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_list_encryption_configs_async.py @@ -50,4 +50,5 @@ async def sample_list_encryption_configs(): async for response in page_result: print(response) + # [END dataplex_v1_generated_CmekService_ListEncryptionConfigs_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_list_encryption_configs_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_list_encryption_configs_sync.py index 6721d3906f0c..9e0ef6fd466f 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_list_encryption_configs_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_list_encryption_configs_sync.py @@ -50,4 +50,5 @@ def sample_list_encryption_configs(): for response in page_result: print(response) + # [END dataplex_v1_generated_CmekService_ListEncryptionConfigs_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_update_encryption_config_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_update_encryption_config_async.py index bcbaaaa68e3d..b97f4121e679 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_update_encryption_config_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_update_encryption_config_async.py @@ -39,8 +39,7 @@ async def sample_update_encryption_config(): client = dataplex_v1.CmekServiceAsyncClient() # Initialize request argument(s) - request = dataplex_v1.UpdateEncryptionConfigRequest( - ) + request = dataplex_v1.UpdateEncryptionConfigRequest() # Make the request operation = client.update_encryption_config(request=request) @@ -52,4 +51,5 @@ async def sample_update_encryption_config(): # Handle the response print(response) + # [END dataplex_v1_generated_CmekService_UpdateEncryptionConfig_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_update_encryption_config_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_update_encryption_config_sync.py index e35470d3489c..2e0ed8171634 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_update_encryption_config_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_cmek_service_update_encryption_config_sync.py @@ -39,8 +39,7 @@ def sample_update_encryption_config(): client = dataplex_v1.CmekServiceClient() # Initialize request argument(s) - request = dataplex_v1.UpdateEncryptionConfigRequest( - ) + request = dataplex_v1.UpdateEncryptionConfigRequest() # Make the request operation = client.update_encryption_config(request=request) @@ -52,4 +51,5 @@ def sample_update_encryption_config(): # Handle the response print(response) + # [END dataplex_v1_generated_CmekService_UpdateEncryptionConfig_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_create_content_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_create_content_async.py index ee8bca70432f..64433e00dbda 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_create_content_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_create_content_async.py @@ -55,4 +55,5 @@ async def sample_create_content(): # Handle the response print(response) + # [END dataplex_v1_generated_ContentService_CreateContent_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_create_content_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_create_content_sync.py index 51ebad7acbc6..d2e4a409c5eb 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_create_content_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_create_content_sync.py @@ -55,4 +55,5 @@ def sample_create_content(): # Handle the response print(response) + # [END dataplex_v1_generated_ContentService_CreateContent_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_get_content_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_get_content_async.py index 8f536a550208..c837bab10277 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_get_content_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_get_content_async.py @@ -49,4 +49,5 @@ async def sample_get_content(): # Handle the response print(response) + # [END dataplex_v1_generated_ContentService_GetContent_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_get_content_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_get_content_sync.py index 99d63ea78c5a..ca3c88375eb0 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_get_content_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_get_content_sync.py @@ -49,4 +49,5 @@ def sample_get_content(): # Handle the response print(response) + # [END dataplex_v1_generated_ContentService_GetContent_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_get_iam_policy_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_get_iam_policy_async.py index b2684491d612..706a35c0748d 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_get_iam_policy_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_get_iam_policy_async.py @@ -23,6 +23,8 @@ # python3 -m pip install google-cloud-dataplex +from google.iam.v1 import iam_policy_pb2 # type: ignore + # [START dataplex_v1_generated_ContentService_GetIamPolicy_async] # This snippet has been automatically generated and should be regarded as a # code template only. @@ -32,7 +34,6 @@ # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html from google.cloud import dataplex_v1 -from google.iam.v1 import iam_policy_pb2 # type: ignore async def sample_get_iam_policy(): @@ -50,4 +51,5 @@ async def sample_get_iam_policy(): # Handle the response print(response) + # [END dataplex_v1_generated_ContentService_GetIamPolicy_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_get_iam_policy_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_get_iam_policy_sync.py index e1c27f30c89c..2e5056cac16a 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_get_iam_policy_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_get_iam_policy_sync.py @@ -23,6 +23,8 @@ # python3 -m pip install google-cloud-dataplex +from google.iam.v1 import iam_policy_pb2 # type: ignore + # [START dataplex_v1_generated_ContentService_GetIamPolicy_sync] # This snippet has been automatically generated and should be regarded as a # code template only. @@ -32,7 +34,6 @@ # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html from google.cloud import dataplex_v1 -from google.iam.v1 import iam_policy_pb2 # type: ignore def sample_get_iam_policy(): @@ -50,4 +51,5 @@ def sample_get_iam_policy(): # Handle the response print(response) + # [END dataplex_v1_generated_ContentService_GetIamPolicy_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_list_content_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_list_content_async.py index fee9a49cd105..2c91822103ed 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_list_content_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_list_content_async.py @@ -50,4 +50,5 @@ async def sample_list_content(): async for response in page_result: print(response) + # [END dataplex_v1_generated_ContentService_ListContent_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_list_content_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_list_content_sync.py index 45cfe1764d91..39d8db5b9db3 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_list_content_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_list_content_sync.py @@ -50,4 +50,5 @@ def sample_list_content(): for response in page_result: print(response) + # [END dataplex_v1_generated_ContentService_ListContent_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_set_iam_policy_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_set_iam_policy_async.py index 23071cd66da7..e95b29c8321f 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_set_iam_policy_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_set_iam_policy_async.py @@ -23,6 +23,8 @@ # python3 -m pip install google-cloud-dataplex +from google.iam.v1 import iam_policy_pb2 # type: ignore + # [START dataplex_v1_generated_ContentService_SetIamPolicy_async] # This snippet has been automatically generated and should be regarded as a # code template only. @@ -32,7 +34,6 @@ # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html from google.cloud import dataplex_v1 -from google.iam.v1 import iam_policy_pb2 # type: ignore async def sample_set_iam_policy(): @@ -50,4 +51,5 @@ async def sample_set_iam_policy(): # Handle the response print(response) + # [END dataplex_v1_generated_ContentService_SetIamPolicy_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_set_iam_policy_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_set_iam_policy_sync.py index 84a85d8c891e..ac9fd9be5167 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_set_iam_policy_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_set_iam_policy_sync.py @@ -23,6 +23,8 @@ # python3 -m pip install google-cloud-dataplex +from google.iam.v1 import iam_policy_pb2 # type: ignore + # [START dataplex_v1_generated_ContentService_SetIamPolicy_sync] # This snippet has been automatically generated and should be regarded as a # code template only. @@ -32,7 +34,6 @@ # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html from google.cloud import dataplex_v1 -from google.iam.v1 import iam_policy_pb2 # type: ignore def sample_set_iam_policy(): @@ -50,4 +51,5 @@ def sample_set_iam_policy(): # Handle the response print(response) + # [END dataplex_v1_generated_ContentService_SetIamPolicy_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_test_iam_permissions_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_test_iam_permissions_async.py index b5b6956a100c..14d82104ab2f 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_test_iam_permissions_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_test_iam_permissions_async.py @@ -23,6 +23,8 @@ # python3 -m pip install google-cloud-dataplex +from google.iam.v1 import iam_policy_pb2 # type: ignore + # [START dataplex_v1_generated_ContentService_TestIamPermissions_async] # This snippet has been automatically generated and should be regarded as a # code template only. @@ -32,7 +34,6 @@ # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html from google.cloud import dataplex_v1 -from google.iam.v1 import iam_policy_pb2 # type: ignore async def sample_test_iam_permissions(): @@ -42,7 +43,7 @@ async def sample_test_iam_permissions(): # Initialize request argument(s) request = iam_policy_pb2.TestIamPermissionsRequest( resource="resource_value", - permissions=['permissions_value1', 'permissions_value2'], + permissions=["permissions_value1", "permissions_value2"], ) # Make the request @@ -51,4 +52,5 @@ async def sample_test_iam_permissions(): # Handle the response print(response) + # [END dataplex_v1_generated_ContentService_TestIamPermissions_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_test_iam_permissions_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_test_iam_permissions_sync.py index 88e6c0a30818..0f8652cbc271 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_test_iam_permissions_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_test_iam_permissions_sync.py @@ -23,6 +23,8 @@ # python3 -m pip install google-cloud-dataplex +from google.iam.v1 import iam_policy_pb2 # type: ignore + # [START dataplex_v1_generated_ContentService_TestIamPermissions_sync] # This snippet has been automatically generated and should be regarded as a # code template only. @@ -32,7 +34,6 @@ # client as shown in: # https://googleapis.dev/python/google-api-core/latest/client_options.html from google.cloud import dataplex_v1 -from google.iam.v1 import iam_policy_pb2 # type: ignore def sample_test_iam_permissions(): @@ -42,7 +43,7 @@ def sample_test_iam_permissions(): # Initialize request argument(s) request = iam_policy_pb2.TestIamPermissionsRequest( resource="resource_value", - permissions=['permissions_value1', 'permissions_value2'], + permissions=["permissions_value1", "permissions_value2"], ) # Make the request @@ -51,4 +52,5 @@ def sample_test_iam_permissions(): # Handle the response print(response) + # [END dataplex_v1_generated_ContentService_TestIamPermissions_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_update_content_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_update_content_async.py index 294c1dc90689..eeae3c22761d 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_update_content_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_update_content_async.py @@ -54,4 +54,5 @@ async def sample_update_content(): # Handle the response print(response) + # [END dataplex_v1_generated_ContentService_UpdateContent_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_update_content_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_update_content_sync.py index 3bd002a75b1c..d21fac812edf 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_update_content_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_content_service_update_content_sync.py @@ -54,4 +54,5 @@ def sample_update_content(): # Handle the response print(response) + # [END dataplex_v1_generated_ContentService_UpdateContent_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_create_data_scan_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_create_data_scan_async.py index 6d7e850f7d00..17f6a076eb37 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_create_data_scan_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_create_data_scan_async.py @@ -59,4 +59,5 @@ async def sample_create_data_scan(): # Handle the response print(response) + # [END dataplex_v1_generated_DataScanService_CreateDataScan_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_create_data_scan_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_create_data_scan_sync.py index 8991dae05723..4b9cc0b5a789 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_create_data_scan_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_create_data_scan_sync.py @@ -59,4 +59,5 @@ def sample_create_data_scan(): # Handle the response print(response) + # [END dataplex_v1_generated_DataScanService_CreateDataScan_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_delete_data_scan_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_delete_data_scan_async.py index 34ba6263ff4b..badf7e07def9 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_delete_data_scan_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_delete_data_scan_async.py @@ -53,4 +53,5 @@ async def sample_delete_data_scan(): # Handle the response print(response) + # [END dataplex_v1_generated_DataScanService_DeleteDataScan_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_delete_data_scan_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_delete_data_scan_sync.py index da530afdeae4..ba565371ad89 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_delete_data_scan_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_delete_data_scan_sync.py @@ -53,4 +53,5 @@ def sample_delete_data_scan(): # Handle the response print(response) + # [END dataplex_v1_generated_DataScanService_DeleteDataScan_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_generate_data_quality_rules_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_generate_data_quality_rules_async.py index 12a8addea03a..56de83c6350f 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_generate_data_quality_rules_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_generate_data_quality_rules_async.py @@ -49,4 +49,5 @@ async def sample_generate_data_quality_rules(): # Handle the response print(response) + # [END dataplex_v1_generated_DataScanService_GenerateDataQualityRules_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_generate_data_quality_rules_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_generate_data_quality_rules_sync.py index 6baafa1eaa02..7efaf09a8715 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_generate_data_quality_rules_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_generate_data_quality_rules_sync.py @@ -49,4 +49,5 @@ def sample_generate_data_quality_rules(): # Handle the response print(response) + # [END dataplex_v1_generated_DataScanService_GenerateDataQualityRules_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_get_data_scan_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_get_data_scan_async.py index b5c832bc848a..e2d19661fbaa 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_get_data_scan_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_get_data_scan_async.py @@ -49,4 +49,5 @@ async def sample_get_data_scan(): # Handle the response print(response) + # [END dataplex_v1_generated_DataScanService_GetDataScan_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_get_data_scan_job_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_get_data_scan_job_async.py index 80598e607389..ea3c8b90bfed 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_get_data_scan_job_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_get_data_scan_job_async.py @@ -49,4 +49,5 @@ async def sample_get_data_scan_job(): # Handle the response print(response) + # [END dataplex_v1_generated_DataScanService_GetDataScanJob_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_get_data_scan_job_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_get_data_scan_job_sync.py index ddac11dcc9f5..287a5c92e716 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_get_data_scan_job_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_get_data_scan_job_sync.py @@ -49,4 +49,5 @@ def sample_get_data_scan_job(): # Handle the response print(response) + # [END dataplex_v1_generated_DataScanService_GetDataScanJob_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_get_data_scan_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_get_data_scan_sync.py index be7a3b9be4c2..acdbb0ef1ca0 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_get_data_scan_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_get_data_scan_sync.py @@ -49,4 +49,5 @@ def sample_get_data_scan(): # Handle the response print(response) + # [END dataplex_v1_generated_DataScanService_GetDataScan_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_list_data_scan_jobs_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_list_data_scan_jobs_async.py index c61c2370d8d4..3ca00cb83053 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_list_data_scan_jobs_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_list_data_scan_jobs_async.py @@ -50,4 +50,5 @@ async def sample_list_data_scan_jobs(): async for response in page_result: print(response) + # [END dataplex_v1_generated_DataScanService_ListDataScanJobs_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_list_data_scan_jobs_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_list_data_scan_jobs_sync.py index f2a0b4655a4f..60285ddade2b 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_list_data_scan_jobs_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_list_data_scan_jobs_sync.py @@ -50,4 +50,5 @@ def sample_list_data_scan_jobs(): for response in page_result: print(response) + # [END dataplex_v1_generated_DataScanService_ListDataScanJobs_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_list_data_scans_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_list_data_scans_async.py index 48c610c9b06c..bebbc74f41b8 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_list_data_scans_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_list_data_scans_async.py @@ -50,4 +50,5 @@ async def sample_list_data_scans(): async for response in page_result: print(response) + # [END dataplex_v1_generated_DataScanService_ListDataScans_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_list_data_scans_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_list_data_scans_sync.py index 92571d491f45..b0999289ac2f 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_list_data_scans_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_list_data_scans_sync.py @@ -50,4 +50,5 @@ def sample_list_data_scans(): for response in page_result: print(response) + # [END dataplex_v1_generated_DataScanService_ListDataScans_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_run_data_scan_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_run_data_scan_async.py index 2fa52865fd65..a232a6434345 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_run_data_scan_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_run_data_scan_async.py @@ -49,4 +49,5 @@ async def sample_run_data_scan(): # Handle the response print(response) + # [END dataplex_v1_generated_DataScanService_RunDataScan_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_run_data_scan_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_run_data_scan_sync.py index 33d96e7d6238..8c8fdda00c41 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_run_data_scan_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_run_data_scan_sync.py @@ -49,4 +49,5 @@ def sample_run_data_scan(): # Handle the response print(response) + # [END dataplex_v1_generated_DataScanService_RunDataScan_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_update_data_scan_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_update_data_scan_async.py index ffcae850e8d9..ba09b94546e0 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_update_data_scan_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_update_data_scan_async.py @@ -57,4 +57,5 @@ async def sample_update_data_scan(): # Handle the response print(response) + # [END dataplex_v1_generated_DataScanService_UpdateDataScan_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_update_data_scan_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_update_data_scan_sync.py index c93c7c383986..7dafd7da30dc 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_update_data_scan_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_scan_service_update_data_scan_sync.py @@ -57,4 +57,5 @@ def sample_update_data_scan(): # Handle the response print(response) + # [END dataplex_v1_generated_DataScanService_UpdateDataScan_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_attribute_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_attribute_async.py index e2b2bf71b387..775288f2025f 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_attribute_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_attribute_async.py @@ -54,4 +54,5 @@ async def sample_create_data_attribute(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_CreateDataAttribute_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_attribute_binding_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_attribute_binding_async.py index beeb5680d9e5..345b03e7f26c 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_attribute_binding_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_attribute_binding_async.py @@ -58,4 +58,5 @@ async def sample_create_data_attribute_binding(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_CreateDataAttributeBinding_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_attribute_binding_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_attribute_binding_sync.py index a3e3aa93857e..63236391e8ef 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_attribute_binding_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_attribute_binding_sync.py @@ -58,4 +58,5 @@ def sample_create_data_attribute_binding(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_CreateDataAttributeBinding_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_attribute_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_attribute_sync.py index d6152220a602..1ac6d75ea0e9 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_attribute_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_attribute_sync.py @@ -54,4 +54,5 @@ def sample_create_data_attribute(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_CreateDataAttribute_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_taxonomy_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_taxonomy_async.py index 99ce40ce34a9..fd43185d32b5 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_taxonomy_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_taxonomy_async.py @@ -54,4 +54,5 @@ async def sample_create_data_taxonomy(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_CreateDataTaxonomy_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_taxonomy_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_taxonomy_sync.py index 772a778084ad..04e3019fcba1 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_taxonomy_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_create_data_taxonomy_sync.py @@ -54,4 +54,5 @@ def sample_create_data_taxonomy(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_CreateDataTaxonomy_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_attribute_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_attribute_async.py index 0e64772d9c22..2c3667311173 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_attribute_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_attribute_async.py @@ -53,4 +53,5 @@ async def sample_delete_data_attribute(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_DeleteDataAttribute_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_attribute_binding_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_attribute_binding_async.py index c477330499b8..5ff7b9aa705a 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_attribute_binding_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_attribute_binding_async.py @@ -54,4 +54,5 @@ async def sample_delete_data_attribute_binding(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_DeleteDataAttributeBinding_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_attribute_binding_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_attribute_binding_sync.py index e364102af74f..f93fcad636a7 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_attribute_binding_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_attribute_binding_sync.py @@ -54,4 +54,5 @@ def sample_delete_data_attribute_binding(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_DeleteDataAttributeBinding_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_attribute_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_attribute_sync.py index 0c151d0cc561..58b694af65e3 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_attribute_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_attribute_sync.py @@ -53,4 +53,5 @@ def sample_delete_data_attribute(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_DeleteDataAttribute_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_taxonomy_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_taxonomy_async.py index b436ccabc9fd..0668092be7dc 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_taxonomy_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_taxonomy_async.py @@ -53,4 +53,5 @@ async def sample_delete_data_taxonomy(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_DeleteDataTaxonomy_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_taxonomy_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_taxonomy_sync.py index bb970218bb82..7b16eacfcb79 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_taxonomy_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_delete_data_taxonomy_sync.py @@ -53,4 +53,5 @@ def sample_delete_data_taxonomy(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_DeleteDataTaxonomy_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_attribute_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_attribute_async.py index 1ef7d2f933b4..1d98df148ee3 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_attribute_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_attribute_async.py @@ -49,4 +49,5 @@ async def sample_get_data_attribute(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_GetDataAttribute_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_attribute_binding_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_attribute_binding_async.py index 3f4a9258be18..0c4cb3f18c4e 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_attribute_binding_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_attribute_binding_async.py @@ -49,4 +49,5 @@ async def sample_get_data_attribute_binding(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_GetDataAttributeBinding_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_attribute_binding_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_attribute_binding_sync.py index 1726b15817dc..6d49414e8eb1 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_attribute_binding_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_attribute_binding_sync.py @@ -49,4 +49,5 @@ def sample_get_data_attribute_binding(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_GetDataAttributeBinding_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_attribute_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_attribute_sync.py index c772287eecea..37adec0525e7 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_attribute_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_attribute_sync.py @@ -49,4 +49,5 @@ def sample_get_data_attribute(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_GetDataAttribute_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_taxonomy_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_taxonomy_async.py index 7001118c3814..7fce0eace5d3 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_taxonomy_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_taxonomy_async.py @@ -49,4 +49,5 @@ async def sample_get_data_taxonomy(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_GetDataTaxonomy_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_taxonomy_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_taxonomy_sync.py index 9171ee6b5c2c..7a66c9415b5c 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_taxonomy_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_get_data_taxonomy_sync.py @@ -49,4 +49,5 @@ def sample_get_data_taxonomy(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_GetDataTaxonomy_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_attribute_bindings_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_attribute_bindings_async.py index ddc48325c378..fe0fdb2367b2 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_attribute_bindings_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_attribute_bindings_async.py @@ -50,4 +50,5 @@ async def sample_list_data_attribute_bindings(): async for response in page_result: print(response) + # [END dataplex_v1_generated_DataTaxonomyService_ListDataAttributeBindings_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_attribute_bindings_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_attribute_bindings_sync.py index a37350712c72..fcba56444fdf 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_attribute_bindings_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_attribute_bindings_sync.py @@ -50,4 +50,5 @@ def sample_list_data_attribute_bindings(): for response in page_result: print(response) + # [END dataplex_v1_generated_DataTaxonomyService_ListDataAttributeBindings_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_attributes_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_attributes_async.py index 884af22fadca..fc4756afc117 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_attributes_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_attributes_async.py @@ -50,4 +50,5 @@ async def sample_list_data_attributes(): async for response in page_result: print(response) + # [END dataplex_v1_generated_DataTaxonomyService_ListDataAttributes_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_attributes_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_attributes_sync.py index ad286e0bccc0..63c796fb9cc6 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_attributes_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_attributes_sync.py @@ -50,4 +50,5 @@ def sample_list_data_attributes(): for response in page_result: print(response) + # [END dataplex_v1_generated_DataTaxonomyService_ListDataAttributes_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_taxonomies_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_taxonomies_async.py index a8e44196d0fe..446f2b4bc2e1 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_taxonomies_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_taxonomies_async.py @@ -50,4 +50,5 @@ async def sample_list_data_taxonomies(): async for response in page_result: print(response) + # [END dataplex_v1_generated_DataTaxonomyService_ListDataTaxonomies_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_taxonomies_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_taxonomies_sync.py index 3199469fe760..274e9286ca70 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_taxonomies_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_list_data_taxonomies_sync.py @@ -50,4 +50,5 @@ def sample_list_data_taxonomies(): for response in page_result: print(response) + # [END dataplex_v1_generated_DataTaxonomyService_ListDataTaxonomies_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_attribute_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_attribute_async.py index 5538cdb101c5..697be9c2e79d 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_attribute_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_attribute_async.py @@ -39,8 +39,7 @@ async def sample_update_data_attribute(): client = dataplex_v1.DataTaxonomyServiceAsyncClient() # Initialize request argument(s) - request = dataplex_v1.UpdateDataAttributeRequest( - ) + request = dataplex_v1.UpdateDataAttributeRequest() # Make the request operation = client.update_data_attribute(request=request) @@ -52,4 +51,5 @@ async def sample_update_data_attribute(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_UpdateDataAttribute_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_attribute_binding_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_attribute_binding_async.py index 003d919da568..467b8ce713ae 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_attribute_binding_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_attribute_binding_async.py @@ -56,4 +56,5 @@ async def sample_update_data_attribute_binding(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_UpdateDataAttributeBinding_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_attribute_binding_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_attribute_binding_sync.py index bcde182293ec..761e9fcd4d26 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_attribute_binding_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_attribute_binding_sync.py @@ -56,4 +56,5 @@ def sample_update_data_attribute_binding(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_UpdateDataAttributeBinding_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_attribute_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_attribute_sync.py index 72938b7a0084..7a3f708ab0d5 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_attribute_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_attribute_sync.py @@ -39,8 +39,7 @@ def sample_update_data_attribute(): client = dataplex_v1.DataTaxonomyServiceClient() # Initialize request argument(s) - request = dataplex_v1.UpdateDataAttributeRequest( - ) + request = dataplex_v1.UpdateDataAttributeRequest() # Make the request operation = client.update_data_attribute(request=request) @@ -52,4 +51,5 @@ def sample_update_data_attribute(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_UpdateDataAttribute_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_taxonomy_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_taxonomy_async.py index d27e74f03f83..82127a7d9039 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_taxonomy_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_taxonomy_async.py @@ -39,8 +39,7 @@ async def sample_update_data_taxonomy(): client = dataplex_v1.DataTaxonomyServiceAsyncClient() # Initialize request argument(s) - request = dataplex_v1.UpdateDataTaxonomyRequest( - ) + request = dataplex_v1.UpdateDataTaxonomyRequest() # Make the request operation = client.update_data_taxonomy(request=request) @@ -52,4 +51,5 @@ async def sample_update_data_taxonomy(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_UpdateDataTaxonomy_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_taxonomy_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_taxonomy_sync.py index e2165abe9e32..b3226addce2c 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_taxonomy_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_data_taxonomy_service_update_data_taxonomy_sync.py @@ -39,8 +39,7 @@ def sample_update_data_taxonomy(): client = dataplex_v1.DataTaxonomyServiceClient() # Initialize request argument(s) - request = dataplex_v1.UpdateDataTaxonomyRequest( - ) + request = dataplex_v1.UpdateDataTaxonomyRequest() # Make the request operation = client.update_data_taxonomy(request=request) @@ -52,4 +51,5 @@ def sample_update_data_taxonomy(): # Handle the response print(response) + # [END dataplex_v1_generated_DataTaxonomyService_UpdateDataTaxonomy_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_asset_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_asset_async.py index 009395cfc039..a70d991e5346 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_asset_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_asset_async.py @@ -58,4 +58,5 @@ async def sample_create_asset(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_CreateAsset_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_asset_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_asset_sync.py index 4c973edec59f..e7e451093ac8 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_asset_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_asset_sync.py @@ -58,4 +58,5 @@ def sample_create_asset(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_CreateAsset_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_environment_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_environment_async.py index c6179d548ca0..afa7eea7c38a 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_environment_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_environment_async.py @@ -58,4 +58,5 @@ async def sample_create_environment(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_CreateEnvironment_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_environment_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_environment_sync.py index 6e83bdaa4850..d8e9be923488 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_environment_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_environment_sync.py @@ -58,4 +58,5 @@ def sample_create_environment(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_CreateEnvironment_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_lake_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_lake_async.py index 9cfc496cdf81..2348db784398 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_lake_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_lake_async.py @@ -54,4 +54,5 @@ async def sample_create_lake(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_CreateLake_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_lake_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_lake_sync.py index 424884d08a39..8f30b9e9d724 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_lake_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_lake_sync.py @@ -54,4 +54,5 @@ def sample_create_lake(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_CreateLake_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_task_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_task_async.py index 570446c72951..d2d4f6eb71ee 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_task_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_task_async.py @@ -61,4 +61,5 @@ async def sample_create_task(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_CreateTask_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_task_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_task_sync.py index 059d6e9caf59..bbb55d0eb892 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_task_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_task_sync.py @@ -61,4 +61,5 @@ def sample_create_task(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_CreateTask_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_zone_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_zone_async.py index 6019acc85718..5aabce9dd40f 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_zone_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_zone_async.py @@ -59,4 +59,5 @@ async def sample_create_zone(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_CreateZone_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_zone_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_zone_sync.py index 6a4caa9ec79d..ad63e0cf8b2c 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_zone_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_create_zone_sync.py @@ -59,4 +59,5 @@ def sample_create_zone(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_CreateZone_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_asset_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_asset_async.py index cb38f16150f4..82a4286a5d01 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_asset_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_asset_async.py @@ -53,4 +53,5 @@ async def sample_delete_asset(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_DeleteAsset_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_asset_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_asset_sync.py index df1f8c9727f0..bc3ff728027d 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_asset_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_asset_sync.py @@ -53,4 +53,5 @@ def sample_delete_asset(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_DeleteAsset_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_environment_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_environment_async.py index e4ddd35aff61..4c2a542c93f0 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_environment_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_environment_async.py @@ -53,4 +53,5 @@ async def sample_delete_environment(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_DeleteEnvironment_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_environment_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_environment_sync.py index bef7a8b3bbc9..8acac287d92f 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_environment_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_environment_sync.py @@ -53,4 +53,5 @@ def sample_delete_environment(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_DeleteEnvironment_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_lake_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_lake_async.py index b471608aca67..f3b0597d442f 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_lake_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_lake_async.py @@ -53,4 +53,5 @@ async def sample_delete_lake(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_DeleteLake_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_lake_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_lake_sync.py index e0712b0d17b8..e5b0530ce8f2 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_lake_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_lake_sync.py @@ -53,4 +53,5 @@ def sample_delete_lake(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_DeleteLake_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_task_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_task_async.py index 770fcc16f1f4..f8ad8a123f2f 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_task_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_task_async.py @@ -53,4 +53,5 @@ async def sample_delete_task(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_DeleteTask_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_task_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_task_sync.py index f467f23478b7..842b30b64e2a 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_task_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_task_sync.py @@ -53,4 +53,5 @@ def sample_delete_task(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_DeleteTask_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_zone_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_zone_async.py index c312b04269ba..6613b7437505 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_zone_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_zone_async.py @@ -53,4 +53,5 @@ async def sample_delete_zone(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_DeleteZone_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_zone_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_zone_sync.py index c13e5cd84601..92c384bb73c0 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_zone_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_delete_zone_sync.py @@ -53,4 +53,5 @@ def sample_delete_zone(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_DeleteZone_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_asset_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_asset_async.py index 93fe6155f85b..570965b3186d 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_asset_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_asset_async.py @@ -49,4 +49,5 @@ async def sample_get_asset(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_GetAsset_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_asset_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_asset_sync.py index 92f815fcbc39..600106c3faac 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_asset_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_asset_sync.py @@ -49,4 +49,5 @@ def sample_get_asset(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_GetAsset_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_environment_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_environment_async.py index c54409b11c2c..b18eca62cbef 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_environment_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_environment_async.py @@ -49,4 +49,5 @@ async def sample_get_environment(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_GetEnvironment_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_environment_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_environment_sync.py index 94f419065b91..25f0f5d655e0 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_environment_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_environment_sync.py @@ -49,4 +49,5 @@ def sample_get_environment(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_GetEnvironment_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_job_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_job_async.py index cd1d8e123e95..c3bb8f70a32c 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_job_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_job_async.py @@ -49,4 +49,5 @@ async def sample_get_job(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_GetJob_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_job_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_job_sync.py index 8b332b6b6de9..6b2b7a11a6b2 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_job_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_job_sync.py @@ -49,4 +49,5 @@ def sample_get_job(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_GetJob_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_lake_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_lake_async.py index b42d72569d47..b65659882bde 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_lake_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_lake_async.py @@ -49,4 +49,5 @@ async def sample_get_lake(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_GetLake_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_lake_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_lake_sync.py index 610dd6b9dabc..916b162e0ab6 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_lake_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_lake_sync.py @@ -49,4 +49,5 @@ def sample_get_lake(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_GetLake_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_task_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_task_async.py index e032ebe67bc5..0eae5aec1055 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_task_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_task_async.py @@ -49,4 +49,5 @@ async def sample_get_task(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_GetTask_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_task_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_task_sync.py index 147f2f6893d0..e3899e9191fd 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_task_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_task_sync.py @@ -49,4 +49,5 @@ def sample_get_task(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_GetTask_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_zone_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_zone_async.py index 99dcf4f47a02..726599b8e45b 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_zone_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_zone_async.py @@ -49,4 +49,5 @@ async def sample_get_zone(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_GetZone_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_zone_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_zone_sync.py index 9f91127efc5f..9770e3c2c243 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_zone_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_get_zone_sync.py @@ -49,4 +49,5 @@ def sample_get_zone(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_GetZone_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_asset_actions_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_asset_actions_async.py index 8845154ecd43..11aebda31618 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_asset_actions_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_asset_actions_async.py @@ -50,4 +50,5 @@ async def sample_list_asset_actions(): async for response in page_result: print(response) + # [END dataplex_v1_generated_DataplexService_ListAssetActions_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_asset_actions_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_asset_actions_sync.py index 417850a8ef86..3336049c7960 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_asset_actions_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_asset_actions_sync.py @@ -50,4 +50,5 @@ def sample_list_asset_actions(): for response in page_result: print(response) + # [END dataplex_v1_generated_DataplexService_ListAssetActions_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_assets_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_assets_async.py index 78a17cdc6cd6..cec11bd9c60d 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_assets_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_assets_async.py @@ -50,4 +50,5 @@ async def sample_list_assets(): async for response in page_result: print(response) + # [END dataplex_v1_generated_DataplexService_ListAssets_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_assets_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_assets_sync.py index b12afd0684d9..80a621f95f71 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_assets_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_assets_sync.py @@ -50,4 +50,5 @@ def sample_list_assets(): for response in page_result: print(response) + # [END dataplex_v1_generated_DataplexService_ListAssets_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_environments_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_environments_async.py index a816672d20ba..a335fb429111 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_environments_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_environments_async.py @@ -50,4 +50,5 @@ async def sample_list_environments(): async for response in page_result: print(response) + # [END dataplex_v1_generated_DataplexService_ListEnvironments_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_environments_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_environments_sync.py index a87c26037b1f..d02d1c53ed07 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_environments_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_environments_sync.py @@ -50,4 +50,5 @@ def sample_list_environments(): for response in page_result: print(response) + # [END dataplex_v1_generated_DataplexService_ListEnvironments_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_jobs_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_jobs_async.py index 519c8b556f56..daff979247ef 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_jobs_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_jobs_async.py @@ -50,4 +50,5 @@ async def sample_list_jobs(): async for response in page_result: print(response) + # [END dataplex_v1_generated_DataplexService_ListJobs_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_jobs_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_jobs_sync.py index 231b588f3d08..f30e1af62e2a 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_jobs_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_jobs_sync.py @@ -50,4 +50,5 @@ def sample_list_jobs(): for response in page_result: print(response) + # [END dataplex_v1_generated_DataplexService_ListJobs_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_lake_actions_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_lake_actions_async.py index b3b3b90becee..e50aa0fc8440 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_lake_actions_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_lake_actions_async.py @@ -50,4 +50,5 @@ async def sample_list_lake_actions(): async for response in page_result: print(response) + # [END dataplex_v1_generated_DataplexService_ListLakeActions_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_lake_actions_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_lake_actions_sync.py index 4eb7cfeacfb1..10c3183896ca 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_lake_actions_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_lake_actions_sync.py @@ -50,4 +50,5 @@ def sample_list_lake_actions(): for response in page_result: print(response) + # [END dataplex_v1_generated_DataplexService_ListLakeActions_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_lakes_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_lakes_async.py index 1821ff51eb42..4d1ef052f878 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_lakes_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_lakes_async.py @@ -50,4 +50,5 @@ async def sample_list_lakes(): async for response in page_result: print(response) + # [END dataplex_v1_generated_DataplexService_ListLakes_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_lakes_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_lakes_sync.py index 30bd707e596c..884e8c7704af 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_lakes_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_lakes_sync.py @@ -50,4 +50,5 @@ def sample_list_lakes(): for response in page_result: print(response) + # [END dataplex_v1_generated_DataplexService_ListLakes_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_sessions_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_sessions_async.py index 87fde35485ec..b1d12d7b06ff 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_sessions_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_sessions_async.py @@ -50,4 +50,5 @@ async def sample_list_sessions(): async for response in page_result: print(response) + # [END dataplex_v1_generated_DataplexService_ListSessions_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_sessions_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_sessions_sync.py index 5e2349662e53..5461b26c3766 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_sessions_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_sessions_sync.py @@ -50,4 +50,5 @@ def sample_list_sessions(): for response in page_result: print(response) + # [END dataplex_v1_generated_DataplexService_ListSessions_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_tasks_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_tasks_async.py index ee1bb7a358f2..b1f6409c78dc 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_tasks_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_tasks_async.py @@ -50,4 +50,5 @@ async def sample_list_tasks(): async for response in page_result: print(response) + # [END dataplex_v1_generated_DataplexService_ListTasks_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_tasks_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_tasks_sync.py index 8d6ea9e99d91..36753b35b265 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_tasks_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_tasks_sync.py @@ -50,4 +50,5 @@ def sample_list_tasks(): for response in page_result: print(response) + # [END dataplex_v1_generated_DataplexService_ListTasks_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_zone_actions_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_zone_actions_async.py index 11d1477126da..dbb7789041a3 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_zone_actions_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_zone_actions_async.py @@ -50,4 +50,5 @@ async def sample_list_zone_actions(): async for response in page_result: print(response) + # [END dataplex_v1_generated_DataplexService_ListZoneActions_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_zone_actions_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_zone_actions_sync.py index f254856503de..daed2223c2d9 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_zone_actions_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_zone_actions_sync.py @@ -50,4 +50,5 @@ def sample_list_zone_actions(): for response in page_result: print(response) + # [END dataplex_v1_generated_DataplexService_ListZoneActions_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_zones_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_zones_async.py index 8a3a26b0f9c8..95c3c20bfce6 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_zones_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_zones_async.py @@ -50,4 +50,5 @@ async def sample_list_zones(): async for response in page_result: print(response) + # [END dataplex_v1_generated_DataplexService_ListZones_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_zones_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_zones_sync.py index 314a861f927e..aeaf03c5deb1 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_zones_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_list_zones_sync.py @@ -50,4 +50,5 @@ def sample_list_zones(): for response in page_result: print(response) + # [END dataplex_v1_generated_DataplexService_ListZones_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_run_task_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_run_task_async.py index ea91643d7ee1..a81c4204abfe 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_run_task_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_run_task_async.py @@ -49,4 +49,5 @@ async def sample_run_task(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_RunTask_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_run_task_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_run_task_sync.py index cca14742d157..28567269f27e 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_run_task_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_run_task_sync.py @@ -49,4 +49,5 @@ def sample_run_task(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_RunTask_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_asset_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_asset_async.py index 1825dd3af6ae..6ea0230cd3d9 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_asset_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_asset_async.py @@ -56,4 +56,5 @@ async def sample_update_asset(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_UpdateAsset_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_asset_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_asset_sync.py index 57a672651f46..f9d1ae23e325 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_asset_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_asset_sync.py @@ -56,4 +56,5 @@ def sample_update_asset(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_UpdateAsset_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_environment_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_environment_async.py index 07d1d4985472..9138f3244cad 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_environment_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_environment_async.py @@ -56,4 +56,5 @@ async def sample_update_environment(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_UpdateEnvironment_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_environment_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_environment_sync.py index b77bfdcee105..19fa1c89a0d4 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_environment_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_environment_sync.py @@ -56,4 +56,5 @@ def sample_update_environment(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_UpdateEnvironment_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_lake_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_lake_async.py index 3d049c83d769..a440c93184e4 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_lake_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_lake_async.py @@ -39,8 +39,7 @@ async def sample_update_lake(): client = dataplex_v1.DataplexServiceAsyncClient() # Initialize request argument(s) - request = dataplex_v1.UpdateLakeRequest( - ) + request = dataplex_v1.UpdateLakeRequest() # Make the request operation = client.update_lake(request=request) @@ -52,4 +51,5 @@ async def sample_update_lake(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_UpdateLake_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_lake_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_lake_sync.py index 334145584703..5a1ac561c1ed 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_lake_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_lake_sync.py @@ -39,8 +39,7 @@ def sample_update_lake(): client = dataplex_v1.DataplexServiceClient() # Initialize request argument(s) - request = dataplex_v1.UpdateLakeRequest( - ) + request = dataplex_v1.UpdateLakeRequest() # Make the request operation = client.update_lake(request=request) @@ -52,4 +51,5 @@ def sample_update_lake(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_UpdateLake_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_task_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_task_async.py index 1f02d2952d62..71c1e12dc8ac 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_task_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_task_async.py @@ -59,4 +59,5 @@ async def sample_update_task(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_UpdateTask_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_task_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_task_sync.py index a7afc9397dc0..11bc82359878 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_task_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_task_sync.py @@ -59,4 +59,5 @@ def sample_update_task(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_UpdateTask_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_zone_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_zone_async.py index 80f26b89522d..e9ee248134f9 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_zone_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_zone_async.py @@ -57,4 +57,5 @@ async def sample_update_zone(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_UpdateZone_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_zone_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_zone_sync.py index ec2683f4dc9f..f62a62f55e65 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_zone_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_dataplex_service_update_zone_sync.py @@ -57,4 +57,5 @@ def sample_update_zone(): # Handle the response print(response) + # [END dataplex_v1_generated_DataplexService_UpdateZone_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_create_entity_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_create_entity_async.py index 0464145a93b4..5b5c9a4d9723 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_create_entity_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_create_entity_async.py @@ -59,4 +59,5 @@ async def sample_create_entity(): # Handle the response print(response) + # [END dataplex_v1_generated_MetadataService_CreateEntity_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_create_entity_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_create_entity_sync.py index fc9b2a1e1368..8e5ceeccd450 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_create_entity_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_create_entity_sync.py @@ -59,4 +59,5 @@ def sample_create_entity(): # Handle the response print(response) + # [END dataplex_v1_generated_MetadataService_CreateEntity_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_create_partition_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_create_partition_async.py index 9ac3bd423a53..0d644f0a92ce 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_create_partition_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_create_partition_async.py @@ -40,7 +40,7 @@ async def sample_create_partition(): # Initialize request argument(s) partition = dataplex_v1.Partition() - partition.values = ['values_value1', 'values_value2'] + partition.values = ["values_value1", "values_value2"] partition.location = "location_value" request = dataplex_v1.CreatePartitionRequest( @@ -54,4 +54,5 @@ async def sample_create_partition(): # Handle the response print(response) + # [END dataplex_v1_generated_MetadataService_CreatePartition_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_create_partition_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_create_partition_sync.py index 68759f52656c..72079e505524 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_create_partition_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_create_partition_sync.py @@ -40,7 +40,7 @@ def sample_create_partition(): # Initialize request argument(s) partition = dataplex_v1.Partition() - partition.values = ['values_value1', 'values_value2'] + partition.values = ["values_value1", "values_value2"] partition.location = "location_value" request = dataplex_v1.CreatePartitionRequest( @@ -54,4 +54,5 @@ def sample_create_partition(): # Handle the response print(response) + # [END dataplex_v1_generated_MetadataService_CreatePartition_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_get_entity_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_get_entity_async.py index 8c6bfd66e0c2..ffb219e27621 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_get_entity_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_get_entity_async.py @@ -49,4 +49,5 @@ async def sample_get_entity(): # Handle the response print(response) + # [END dataplex_v1_generated_MetadataService_GetEntity_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_get_entity_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_get_entity_sync.py index 91400bfc9e7d..abdcbf958107 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_get_entity_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_get_entity_sync.py @@ -49,4 +49,5 @@ def sample_get_entity(): # Handle the response print(response) + # [END dataplex_v1_generated_MetadataService_GetEntity_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_get_partition_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_get_partition_async.py index bdd927959bcb..f38963bf7326 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_get_partition_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_get_partition_async.py @@ -49,4 +49,5 @@ async def sample_get_partition(): # Handle the response print(response) + # [END dataplex_v1_generated_MetadataService_GetPartition_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_get_partition_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_get_partition_sync.py index b5fb1a52ecf6..f8df3fd33532 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_get_partition_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_get_partition_sync.py @@ -49,4 +49,5 @@ def sample_get_partition(): # Handle the response print(response) + # [END dataplex_v1_generated_MetadataService_GetPartition_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_list_entities_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_list_entities_async.py index 39c288b6c43e..8ac681b72168 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_list_entities_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_list_entities_async.py @@ -51,4 +51,5 @@ async def sample_list_entities(): async for response in page_result: print(response) + # [END dataplex_v1_generated_MetadataService_ListEntities_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_list_entities_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_list_entities_sync.py index f03b686a369a..600c5351f260 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_list_entities_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_list_entities_sync.py @@ -51,4 +51,5 @@ def sample_list_entities(): for response in page_result: print(response) + # [END dataplex_v1_generated_MetadataService_ListEntities_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_list_partitions_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_list_partitions_async.py index cbd82d4433a4..16384686cfdd 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_list_partitions_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_list_partitions_async.py @@ -50,4 +50,5 @@ async def sample_list_partitions(): async for response in page_result: print(response) + # [END dataplex_v1_generated_MetadataService_ListPartitions_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_list_partitions_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_list_partitions_sync.py index 2854a45a94a1..7b641a687c17 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_list_partitions_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_list_partitions_sync.py @@ -50,4 +50,5 @@ def sample_list_partitions(): for response in page_result: print(response) + # [END dataplex_v1_generated_MetadataService_ListPartitions_sync] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_update_entity_async.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_update_entity_async.py index 6f6d1525a4c4..adfc57618cf8 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_update_entity_async.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_update_entity_async.py @@ -58,4 +58,5 @@ async def sample_update_entity(): # Handle the response print(response) + # [END dataplex_v1_generated_MetadataService_UpdateEntity_async] diff --git a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_update_entity_sync.py b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_update_entity_sync.py index fa71e34d815b..32e124bcd09c 100644 --- a/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_update_entity_sync.py +++ b/packages/google-cloud-dataplex/samples/generated_samples/dataplex_v1_generated_metadata_service_update_entity_sync.py @@ -58,4 +58,5 @@ def sample_update_entity(): # Handle the response print(response) + # [END dataplex_v1_generated_MetadataService_UpdateEntity_sync] diff --git a/packages/google-cloud-dataplex/tests/unit/gapic/dataplex_v1/test_catalog_service.py b/packages/google-cloud-dataplex/tests/unit/gapic/dataplex_v1/test_catalog_service.py index 87518b65c369..e1c92a40dd01 100644 --- a/packages/google-cloud-dataplex/tests/unit/gapic/dataplex_v1/test_catalog_service.py +++ b/packages/google-cloud-dataplex/tests/unit/gapic/dataplex_v1/test_catalog_service.py @@ -4705,6 +4705,7 @@ def test_get_aspect_type(request_type, transport: str = "grpc"): description="description_value", display_name="display_name_value", etag="etag_value", + data_classification=catalog.AspectType.DataClassification.METADATA_AND_DATA, transfer_status=catalog.TransferStatus.TRANSFER_STATUS_MIGRATED, ) response = client.get_aspect_type(request) @@ -4722,6 +4723,10 @@ def test_get_aspect_type(request_type, transport: str = "grpc"): assert response.description == "description_value" assert response.display_name == "display_name_value" assert response.etag == "etag_value" + assert ( + response.data_classification + == catalog.AspectType.DataClassification.METADATA_AND_DATA + ) assert response.transfer_status == catalog.TransferStatus.TRANSFER_STATUS_MIGRATED @@ -4853,6 +4858,7 @@ async def test_get_aspect_type_async( description="description_value", display_name="display_name_value", etag="etag_value", + data_classification=catalog.AspectType.DataClassification.METADATA_AND_DATA, transfer_status=catalog.TransferStatus.TRANSFER_STATUS_MIGRATED, ) ) @@ -4871,6 +4877,10 @@ async def test_get_aspect_type_async( assert response.description == "description_value" assert response.display_name == "display_name_value" assert response.etag == "etag_value" + assert ( + response.data_classification + == catalog.AspectType.DataClassification.METADATA_AND_DATA + ) assert response.transfer_status == catalog.TransferStatus.TRANSFER_STATUS_MIGRATED @@ -19278,6 +19288,7 @@ async def test_get_aspect_type_empty_call_grpc_asyncio(): description="description_value", display_name="display_name_value", etag="etag_value", + data_classification=catalog.AspectType.DataClassification.METADATA_AND_DATA, transfer_status=catalog.TransferStatus.TRANSFER_STATUS_MIGRATED, ) ) @@ -20689,6 +20700,7 @@ def test_create_aspect_type_rest_call_success(request_type): "display_name": "display_name_value", "labels": {}, "etag": "etag_value", + "data_classification": 1, "authorization": {"alternate_use_permission": "alternate_use_permission_value"}, "metadata_template": { "index": 536, @@ -20922,6 +20934,7 @@ def test_update_aspect_type_rest_call_success(request_type): "display_name": "display_name_value", "labels": {}, "etag": "etag_value", + "data_classification": 1, "authorization": {"alternate_use_permission": "alternate_use_permission_value"}, "metadata_template": { "index": 536, @@ -21400,6 +21413,7 @@ def test_get_aspect_type_rest_call_success(request_type): description="description_value", display_name="display_name_value", etag="etag_value", + data_classification=catalog.AspectType.DataClassification.METADATA_AND_DATA, transfer_status=catalog.TransferStatus.TRANSFER_STATUS_MIGRATED, ) @@ -21422,6 +21436,10 @@ def test_get_aspect_type_rest_call_success(request_type): assert response.description == "description_value" assert response.display_name == "display_name_value" assert response.etag == "etag_value" + assert ( + response.data_classification + == catalog.AspectType.DataClassification.METADATA_AND_DATA + ) assert response.transfer_status == catalog.TransferStatus.TRANSFER_STATUS_MIGRATED diff --git a/packages/google-cloud-dataplex/tests/unit/gapic/dataplex_v1/test_cmek_service.py b/packages/google-cloud-dataplex/tests/unit/gapic/dataplex_v1/test_cmek_service.py index 12660b05f4da..c68b674e4e52 100644 --- a/packages/google-cloud-dataplex/tests/unit/gapic/dataplex_v1/test_cmek_service.py +++ b/packages/google-cloud-dataplex/tests/unit/gapic/dataplex_v1/test_cmek_service.py @@ -2739,6 +2739,7 @@ def test_get_encryption_config(request_type, transport: str = "grpc"): key="key_value", encryption_state=cmek.EncryptionConfig.EncryptionState.ENCRYPTING, etag="etag_value", + enable_metastore_encryption=True, ) response = client.get_encryption_config(request) @@ -2754,6 +2755,7 @@ def test_get_encryption_config(request_type, transport: str = "grpc"): assert response.key == "key_value" assert response.encryption_state == cmek.EncryptionConfig.EncryptionState.ENCRYPTING assert response.etag == "etag_value" + assert response.enable_metastore_encryption is True def test_get_encryption_config_non_empty_request_with_auto_populated_field(): @@ -2892,6 +2894,7 @@ async def test_get_encryption_config_async( key="key_value", encryption_state=cmek.EncryptionConfig.EncryptionState.ENCRYPTING, etag="etag_value", + enable_metastore_encryption=True, ) ) response = await client.get_encryption_config(request) @@ -2908,6 +2911,7 @@ async def test_get_encryption_config_async( assert response.key == "key_value" assert response.encryption_state == cmek.EncryptionConfig.EncryptionState.ENCRYPTING assert response.etag == "etag_value" + assert response.enable_metastore_encryption is True @pytest.mark.asyncio @@ -4467,6 +4471,7 @@ async def test_get_encryption_config_empty_call_grpc_asyncio(): key="key_value", encryption_state=cmek.EncryptionConfig.EncryptionState.ENCRYPTING, etag="etag_value", + enable_metastore_encryption=True, ) ) await client.get_encryption_config(request=None) @@ -4533,6 +4538,7 @@ def test_create_encryption_config_rest_call_success(request_type): "encryption_state": 1, "etag": "etag_value", "failure_details": {"error_code": 1, "error_message": "error_message_value"}, + "enable_metastore_encryption": True, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -4741,6 +4747,7 @@ def test_update_encryption_config_rest_call_success(request_type): "encryption_state": 1, "etag": "etag_value", "failure_details": {"error_code": 1, "error_message": "error_message_value"}, + "enable_metastore_encryption": True, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -5207,6 +5214,7 @@ def test_get_encryption_config_rest_call_success(request_type): key="key_value", encryption_state=cmek.EncryptionConfig.EncryptionState.ENCRYPTING, etag="etag_value", + enable_metastore_encryption=True, ) # Wrap the value into a proper Response obj @@ -5227,6 +5235,7 @@ def test_get_encryption_config_rest_call_success(request_type): assert response.key == "key_value" assert response.encryption_state == cmek.EncryptionConfig.EncryptionState.ENCRYPTING assert response.etag == "etag_value" + assert response.enable_metastore_encryption is True @pytest.mark.parametrize("null_interceptor", [True, False]) diff --git a/packages/google-cloud-dataplex/tests/unit/gapic/dataplex_v1/test_data_scan_service.py b/packages/google-cloud-dataplex/tests/unit/gapic/dataplex_v1/test_data_scan_service.py index ab973c7dc066..ecb5eb2e9892 100644 --- a/packages/google-cloud-dataplex/tests/unit/gapic/dataplex_v1/test_data_scan_service.py +++ b/packages/google-cloud-dataplex/tests/unit/gapic/dataplex_v1/test_data_scan_service.py @@ -77,6 +77,7 @@ ) from google.cloud.dataplex_v1.types import ( data_discovery, + data_documentation, data_profile, data_quality, datascans, @@ -7162,6 +7163,7 @@ def test_create_data_scan_rest_call_success(request_type): }, }, }, + "data_documentation_spec": {}, "data_quality_result": { "passed": True, "score": 0.54, @@ -7200,6 +7202,12 @@ def test_create_data_scan_rest_call_success(request_type): "bigquery_export_result": {"state": 1, "message": "message_value"} }, "catalog_publishing_status": {"state": 1}, + "anomaly_detection_generated_assets": { + "result_table": "result_table_value", + "data_intermediate_table": "data_intermediate_table_value", + "freshness_intermediate_table": "freshness_intermediate_table_value", + "volume_intermediate_table": "volume_intermediate_table_value", + }, }, "data_profile_result": { "row_count": 992, @@ -7260,6 +7268,22 @@ def test_create_data_scan_rest_call_success(request_type): "filesets_updated": 1701, }, }, + "data_documentation_result": { + "table_result": { + "name": "name_value", + "overview": "overview_value", + "schema": { + "fields": [ + { + "name": "name_value", + "description": "description_value", + "fields": {}, + } + ] + }, + "queries": [{"sql": "sql_value", "description": "description_value"}], + } + }, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -7564,6 +7588,7 @@ def test_update_data_scan_rest_call_success(request_type): }, }, }, + "data_documentation_spec": {}, "data_quality_result": { "passed": True, "score": 0.54, @@ -7602,6 +7627,12 @@ def test_update_data_scan_rest_call_success(request_type): "bigquery_export_result": {"state": 1, "message": "message_value"} }, "catalog_publishing_status": {"state": 1}, + "anomaly_detection_generated_assets": { + "result_table": "result_table_value", + "data_intermediate_table": "data_intermediate_table_value", + "freshness_intermediate_table": "freshness_intermediate_table_value", + "volume_intermediate_table": "volume_intermediate_table_value", + }, }, "data_profile_result": { "row_count": 992, @@ -7662,6 +7693,22 @@ def test_update_data_scan_rest_call_success(request_type): "filesets_updated": 1701, }, }, + "data_documentation_result": { + "table_result": { + "name": "name_value", + "overview": "overview_value", + "schema": { + "fields": [ + { + "name": "name_value", + "description": "description_value", + "fields": {}, + } + ] + }, + "queries": [{"sql": "sql_value", "description": "description_value"}], + } + }, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency diff --git a/packages/google-cloud-dialogflow/docs/dialogflow_v2beta1/generator_evaluations.rst b/packages/google-cloud-dialogflow/docs/dialogflow_v2beta1/generator_evaluations.rst new file mode 100644 index 000000000000..e18d86be5593 --- /dev/null +++ b/packages/google-cloud-dialogflow/docs/dialogflow_v2beta1/generator_evaluations.rst @@ -0,0 +1,10 @@ +GeneratorEvaluations +-------------------------------------- + +.. automodule:: google.cloud.dialogflow_v2beta1.services.generator_evaluations + :members: + :inherited-members: + +.. automodule:: google.cloud.dialogflow_v2beta1.services.generator_evaluations.pagers + :members: + :inherited-members: diff --git a/packages/google-cloud-dialogflow/docs/dialogflow_v2beta1/services_.rst b/packages/google-cloud-dialogflow/docs/dialogflow_v2beta1/services_.rst index 134d34945f5c..4b3704c74f53 100644 --- a/packages/google-cloud-dialogflow/docs/dialogflow_v2beta1/services_.rst +++ b/packages/google-cloud-dialogflow/docs/dialogflow_v2beta1/services_.rst @@ -13,6 +13,7 @@ Services for Google Cloud Dialogflow v2beta1 API entity_types environments fulfillments + generator_evaluations generators intents knowledge_bases @@ -21,4 +22,5 @@ Services for Google Cloud Dialogflow v2beta1 API session_entity_types sessions sip_trunks + tools versions diff --git a/packages/google-cloud-dialogflow/docs/dialogflow_v2beta1/tools.rst b/packages/google-cloud-dialogflow/docs/dialogflow_v2beta1/tools.rst new file mode 100644 index 000000000000..8ce1e56766a0 --- /dev/null +++ b/packages/google-cloud-dialogflow/docs/dialogflow_v2beta1/tools.rst @@ -0,0 +1,10 @@ +Tools +----------------------- + +.. automodule:: google.cloud.dialogflow_v2beta1.services.tools + :members: + :inherited-members: + +.. automodule:: google.cloud.dialogflow_v2beta1.services.tools.pagers + :members: + :inherited-members: diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/__init__.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/__init__.py index 44b640e958b0..28251d6c8b81 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/__init__.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/__init__.py @@ -34,6 +34,10 @@ from .services.entity_types import EntityTypesAsyncClient, EntityTypesClient from .services.environments import EnvironmentsAsyncClient, EnvironmentsClient from .services.fulfillments import FulfillmentsAsyncClient, FulfillmentsClient +from .services.generator_evaluations import ( + GeneratorEvaluationsAsyncClient, + GeneratorEvaluationsClient, +) from .services.generators import GeneratorsAsyncClient, GeneratorsClient from .services.intents import IntentsAsyncClient, IntentsClient from .services.knowledge_bases import KnowledgeBasesAsyncClient, KnowledgeBasesClient @@ -45,6 +49,7 @@ ) from .services.sessions import SessionsAsyncClient, SessionsClient from .services.sip_trunks import SipTrunksAsyncClient, SipTrunksClient +from .services.tools import ToolsAsyncClient, ToolsClient from .services.versions import VersionsAsyncClient, VersionsClient from .types.agent import ( Agent, @@ -61,6 +66,7 @@ SubAgent, TrainAgentRequest, ) +from .types.agent_coaching_instruction import AgentCoachingInstruction from .types.answer_record import ( AgentAssistantFeedback, AgentAssistantRecord, @@ -74,6 +80,7 @@ from .types.audio_config import ( AudioEncoding, BargeInConfig, + CustomPronunciationParams, InputAudioConfig, OutputAudioConfig, OutputAudioEncoding, @@ -199,6 +206,8 @@ ) from .types.gcs import GcsDestination, GcsSource, GcsSources from .types.generator import ( + AgentCoachingContext, + AgentCoachingSuggestion, ConversationContext, CreateGeneratorRequest, DeleteGeneratorRequest, @@ -212,6 +221,8 @@ ListGeneratorsRequest, ListGeneratorsResponse, MessageEntry, + RaiSettings, + SuggestionDedupingConfig, SummarizationContext, SummarizationSection, SummarizationSectionList, @@ -219,6 +230,17 @@ TriggerEvent, UpdateGeneratorRequest, ) +from .types.generator_evaluation import ( + CreateGeneratorEvaluationRequest, + DeleteGeneratorEvaluationRequest, + EvaluationStatus, + GeneratorEvaluation, + GeneratorEvaluationConfig, + GetGeneratorEvaluationRequest, + ListGeneratorEvaluationsRequest, + ListGeneratorEvaluationsResponse, + SummarizationEvaluationMetrics, +) from .types.human_agent_assistant_event import HumanAgentAssistantEvent from .types.intent import ( BatchDeleteIntentsRequest, @@ -243,6 +265,7 @@ ListKnowledgeBasesResponse, UpdateKnowledgeBaseRequest, ) +from .types.operations import GeneratorEvaluationOperationMetadata from .types.participant import ( AnalyzeContentRequest, AnalyzeContentResponse, @@ -251,6 +274,8 @@ AssistQueryParameters, AudioInput, AutomatedAgentReply, + BidiStreamingAnalyzeContentRequest, + BidiStreamingAnalyzeContentResponse, CompileSuggestionRequest, CompileSuggestionResponse, CreateParticipantRequest, @@ -334,6 +359,16 @@ SipTrunk, UpdateSipTrunkRequest, ) +from .types.tool import ( + CreateToolRequest, + DeleteToolRequest, + GetToolRequest, + ListToolsRequest, + ListToolsResponse, + Tool, + UpdateToolRequest, +) +from .types.tool_call import ToolCall, ToolCallResult from .types.validation_result import ValidationError, ValidationResult from .types.version import ( CreateVersionRequest, @@ -357,6 +392,7 @@ "EntityTypesAsyncClient", "EnvironmentsAsyncClient", "FulfillmentsAsyncClient", + "GeneratorEvaluationsAsyncClient", "GeneratorsAsyncClient", "IntentsAsyncClient", "KnowledgeBasesAsyncClient", @@ -365,10 +401,14 @@ "SessionEntityTypesAsyncClient", "SessionsAsyncClient", "SipTrunksAsyncClient", + "ToolsAsyncClient", "VersionsAsyncClient", "Agent", "AgentAssistantFeedback", "AgentAssistantRecord", + "AgentCoachingContext", + "AgentCoachingInstruction", + "AgentCoachingSuggestion", "AgentsClient", "AnalyzeContentRequest", "AnalyzeContentResponse", @@ -394,6 +434,8 @@ "BatchUpdateEntityTypesResponse", "BatchUpdateIntentsRequest", "BatchUpdateIntentsResponse", + "BidiStreamingAnalyzeContentRequest", + "BidiStreamingAnalyzeContentResponse", "ClearSuggestionFeatureConfigOperationMetadata", "ClearSuggestionFeatureConfigRequest", "CloudConversationDebuggingInfo", @@ -416,6 +458,7 @@ "CreateDocumentRequest", "CreateEntityTypeRequest", "CreateEnvironmentRequest", + "CreateGeneratorEvaluationRequest", "CreateGeneratorRequest", "CreateIntentRequest", "CreateKnowledgeBaseRequest", @@ -423,7 +466,9 @@ "CreateParticipantRequest", "CreateSessionEntityTypeRequest", "CreateSipTrunkRequest", + "CreateToolRequest", "CreateVersionRequest", + "CustomPronunciationParams", "DeleteAgentRequest", "DeleteAllContextsRequest", "DeleteContextRequest", @@ -431,12 +476,14 @@ "DeleteDocumentRequest", "DeleteEntityTypeRequest", "DeleteEnvironmentRequest", + "DeleteGeneratorEvaluationRequest", "DeleteGeneratorRequest", "DeleteIntentRequest", "DeleteKnowledgeBaseRequest", "DeletePhoneNumberRequest", "DeleteSessionEntityTypeRequest", "DeleteSipTrunkRequest", + "DeleteToolRequest", "DeleteVersionRequest", "DetectIntentRequest", "DetectIntentResponse", @@ -452,6 +499,7 @@ "Environment", "EnvironmentHistory", "EnvironmentsClient", + "EvaluationStatus", "EventInput", "ExportAgentRequest", "ExportAgentResponse", @@ -472,6 +520,10 @@ "GenerateSuggestionsRequest", "GenerateSuggestionsResponse", "Generator", + "GeneratorEvaluation", + "GeneratorEvaluationConfig", + "GeneratorEvaluationOperationMetadata", + "GeneratorEvaluationsClient", "GeneratorSuggestion", "GeneratorsClient", "GetAgentRequest", @@ -485,12 +537,14 @@ "GetEnvironmentHistoryRequest", "GetEnvironmentRequest", "GetFulfillmentRequest", + "GetGeneratorEvaluationRequest", "GetGeneratorRequest", "GetIntentRequest", "GetKnowledgeBaseRequest", "GetParticipantRequest", "GetSessionEntityTypeRequest", "GetSipTrunkRequest", + "GetToolRequest", "GetValidationResultRequest", "GetVersionRequest", "HumanAgentAssistantConfig", @@ -533,6 +587,8 @@ "ListEntityTypesResponse", "ListEnvironmentsRequest", "ListEnvironmentsResponse", + "ListGeneratorEvaluationsRequest", + "ListGeneratorEvaluationsResponse", "ListGeneratorsRequest", "ListGeneratorsResponse", "ListIntentsRequest", @@ -551,6 +607,8 @@ "ListSipTrunksResponse", "ListSuggestionsRequest", "ListSuggestionsResponse", + "ListToolsRequest", + "ListToolsResponse", "ListVersionsRequest", "ListVersionsResponse", "LoggingConfig", @@ -569,6 +627,7 @@ "QueryInput", "QueryParameters", "QueryResult", + "RaiSettings", "ReloadDocumentRequest", "ResponseMessage", "RestoreAgentRequest", @@ -612,10 +671,12 @@ "SuggestSmartRepliesRequest", "SuggestSmartRepliesResponse", "Suggestion", + "SuggestionDedupingConfig", "SuggestionFeature", "SuggestionInput", "SuggestionResult", "SummarizationContext", + "SummarizationEvaluationMetrics", "SummarizationSection", "SummarizationSectionList", "SummarySuggestion", @@ -624,6 +685,10 @@ "TelephonyDtmfEvents", "TextInput", "TextToSpeechSettings", + "Tool", + "ToolCall", + "ToolCallResult", + "ToolsClient", "TrainAgentRequest", "TriggerEvent", "UndeletePhoneNumberRequest", @@ -641,6 +706,7 @@ "UpdatePhoneNumberRequest", "UpdateSessionEntityTypeRequest", "UpdateSipTrunkRequest", + "UpdateToolRequest", "UpdateVersionRequest", "ValidationError", "ValidationResult", diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/gapic_metadata.json b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/gapic_metadata.json index eb9cae9beca3..0b22e870ce17 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/gapic_metadata.json +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/gapic_metadata.json @@ -1155,6 +1155,85 @@ } } }, + "GeneratorEvaluations": { + "clients": { + "grpc": { + "libraryClient": "GeneratorEvaluationsClient", + "rpcs": { + "CreateGeneratorEvaluation": { + "methods": [ + "create_generator_evaluation" + ] + }, + "DeleteGeneratorEvaluation": { + "methods": [ + "delete_generator_evaluation" + ] + }, + "GetGeneratorEvaluation": { + "methods": [ + "get_generator_evaluation" + ] + }, + "ListGeneratorEvaluations": { + "methods": [ + "list_generator_evaluations" + ] + } + } + }, + "grpc-async": { + "libraryClient": "GeneratorEvaluationsAsyncClient", + "rpcs": { + "CreateGeneratorEvaluation": { + "methods": [ + "create_generator_evaluation" + ] + }, + "DeleteGeneratorEvaluation": { + "methods": [ + "delete_generator_evaluation" + ] + }, + "GetGeneratorEvaluation": { + "methods": [ + "get_generator_evaluation" + ] + }, + "ListGeneratorEvaluations": { + "methods": [ + "list_generator_evaluations" + ] + } + } + }, + "rest": { + "libraryClient": "GeneratorEvaluationsClient", + "rpcs": { + "CreateGeneratorEvaluation": { + "methods": [ + "create_generator_evaluation" + ] + }, + "DeleteGeneratorEvaluation": { + "methods": [ + "delete_generator_evaluation" + ] + }, + "GetGeneratorEvaluation": { + "methods": [ + "get_generator_evaluation" + ] + }, + "ListGeneratorEvaluations": { + "methods": [ + "list_generator_evaluations" + ] + } + } + } + } + }, "Generators": { "clients": { "grpc": { @@ -1477,6 +1556,11 @@ "analyze_content" ] }, + "BidiStreamingAnalyzeContent": { + "methods": [ + "bidi_streaming_analyze_content" + ] + }, "CompileSuggestion": { "methods": [ "compile_suggestion" @@ -1542,6 +1626,11 @@ "analyze_content" ] }, + "BidiStreamingAnalyzeContent": { + "methods": [ + "bidi_streaming_analyze_content" + ] + }, "CompileSuggestion": { "methods": [ "compile_suggestion" @@ -1607,6 +1696,11 @@ "analyze_content" ] }, + "BidiStreamingAnalyzeContent": { + "methods": [ + "bidi_streaming_analyze_content" + ] + }, "CompileSuggestion": { "methods": [ "compile_suggestion" @@ -1982,6 +2076,100 @@ } } }, + "Tools": { + "clients": { + "grpc": { + "libraryClient": "ToolsClient", + "rpcs": { + "CreateTool": { + "methods": [ + "create_tool" + ] + }, + "DeleteTool": { + "methods": [ + "delete_tool" + ] + }, + "GetTool": { + "methods": [ + "get_tool" + ] + }, + "ListTools": { + "methods": [ + "list_tools" + ] + }, + "UpdateTool": { + "methods": [ + "update_tool" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ToolsAsyncClient", + "rpcs": { + "CreateTool": { + "methods": [ + "create_tool" + ] + }, + "DeleteTool": { + "methods": [ + "delete_tool" + ] + }, + "GetTool": { + "methods": [ + "get_tool" + ] + }, + "ListTools": { + "methods": [ + "list_tools" + ] + }, + "UpdateTool": { + "methods": [ + "update_tool" + ] + } + } + }, + "rest": { + "libraryClient": "ToolsClient", + "rpcs": { + "CreateTool": { + "methods": [ + "create_tool" + ] + }, + "DeleteTool": { + "methods": [ + "delete_tool" + ] + }, + "GetTool": { + "methods": [ + "get_tool" + ] + }, + "ListTools": { + "methods": [ + "list_tools" + ] + }, + "UpdateTool": { + "methods": [ + "update_tool" + ] + } + } + } + } + }, "Versions": { "clients": { "grpc": { diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/answer_records/async_client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/answer_records/async_client.py index 7b9eea372b86..4986895f6661 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/answer_records/async_client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/answer_records/async_client.py @@ -91,6 +91,8 @@ class AnswerRecordsAsyncClient: parse_document_path = staticmethod(AnswerRecordsClient.parse_document_path) intent_path = staticmethod(AnswerRecordsClient.intent_path) parse_intent_path = staticmethod(AnswerRecordsClient.parse_intent_path) + tool_path = staticmethod(AnswerRecordsClient.tool_path) + parse_tool_path = staticmethod(AnswerRecordsClient.parse_tool_path) common_billing_account_path = staticmethod( AnswerRecordsClient.common_billing_account_path ) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/answer_records/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/answer_records/client.py index ef9bf5b44f8f..75e31c28679c 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/answer_records/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/answer_records/client.py @@ -281,6 +281,28 @@ def parse_intent_path(path: str) -> Dict[str, str]: m = re.match(r"^projects/(?P.+?)/agent/intents/(?P.+?)$", path) return m.groupdict() if m else {} + @staticmethod + def tool_path( + project: str, + location: str, + tool: str, + ) -> str: + """Returns a fully-qualified tool string.""" + return "projects/{project}/locations/{location}/tools/{tool}".format( + project=project, + location=location, + tool=tool, + ) + + @staticmethod + def parse_tool_path(path: str) -> Dict[str, str]: + """Parses a tool path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/tools/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def common_billing_account_path( billing_account: str, diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/async_client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/async_client.py index 7e323c3f3b86..5cf4017fa432 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/async_client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/async_client.py @@ -119,6 +119,8 @@ class ConversationsAsyncClient: parse_message_path = staticmethod(ConversationsClient.parse_message_path) phrase_set_path = staticmethod(ConversationsClient.phrase_set_path) parse_phrase_set_path = staticmethod(ConversationsClient.parse_phrase_set_path) + tool_path = staticmethod(ConversationsClient.tool_path) + parse_tool_path = staticmethod(ConversationsClient.parse_tool_path) common_billing_account_path = staticmethod( ConversationsClient.common_billing_account_path ) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/client.py index 3bd02c0c48f5..624e5919d0e0 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/client.py @@ -452,6 +452,28 @@ def parse_phrase_set_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def tool_path( + project: str, + location: str, + tool: str, + ) -> str: + """Returns a fully-qualified tool string.""" + return "projects/{project}/locations/{location}/tools/{tool}".format( + project=project, + location=location, + tool=tool, + ) + + @staticmethod + def parse_tool_path(path: str) -> Dict[str, str]: + """Parses a tool path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/tools/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def common_billing_account_path( billing_account: str, diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/__init__.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/__init__.py new file mode 100644 index 000000000000..a1748a446f71 --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/__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 .async_client import GeneratorEvaluationsAsyncClient +from .client import GeneratorEvaluationsClient + +__all__ = ( + "GeneratorEvaluationsClient", + "GeneratorEvaluationsAsyncClient", +) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/async_client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/async_client.py new file mode 100644 index 000000000000..083a4e27cea3 --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/async_client.py @@ -0,0 +1,1098 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 +import logging as std_logging +import re +from typing import ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, +) + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.api_core.client_options import ClientOptions +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.cloud.dialogflow_v2beta1 import gapic_version as package_version + +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.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + +from google.cloud.dialogflow_v2beta1.services.generator_evaluations import pagers +from google.cloud.dialogflow_v2beta1.types import ( + generator_evaluation as gcd_generator_evaluation, +) +from google.cloud.dialogflow_v2beta1.types import generator +from google.cloud.dialogflow_v2beta1.types import generator_evaluation +from google.cloud.dialogflow_v2beta1.types import operations + +from .client import GeneratorEvaluationsClient +from .transports.base import DEFAULT_CLIENT_INFO, GeneratorEvaluationsTransport +from .transports.grpc_asyncio import GeneratorEvaluationsGrpcAsyncIOTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class GeneratorEvaluationsAsyncClient: + """Service for managing generator evaluations.""" + + _client: GeneratorEvaluationsClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = GeneratorEvaluationsClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = GeneratorEvaluationsClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = GeneratorEvaluationsClient._DEFAULT_ENDPOINT_TEMPLATE + _DEFAULT_UNIVERSE = GeneratorEvaluationsClient._DEFAULT_UNIVERSE + + generator_path = staticmethod(GeneratorEvaluationsClient.generator_path) + parse_generator_path = staticmethod(GeneratorEvaluationsClient.parse_generator_path) + generator_evaluation_path = staticmethod( + GeneratorEvaluationsClient.generator_evaluation_path + ) + parse_generator_evaluation_path = staticmethod( + GeneratorEvaluationsClient.parse_generator_evaluation_path + ) + tool_path = staticmethod(GeneratorEvaluationsClient.tool_path) + parse_tool_path = staticmethod(GeneratorEvaluationsClient.parse_tool_path) + common_billing_account_path = staticmethod( + GeneratorEvaluationsClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + GeneratorEvaluationsClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(GeneratorEvaluationsClient.common_folder_path) + parse_common_folder_path = staticmethod( + GeneratorEvaluationsClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + GeneratorEvaluationsClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + GeneratorEvaluationsClient.parse_common_organization_path + ) + common_project_path = staticmethod(GeneratorEvaluationsClient.common_project_path) + parse_common_project_path = staticmethod( + GeneratorEvaluationsClient.parse_common_project_path + ) + common_location_path = staticmethod(GeneratorEvaluationsClient.common_location_path) + parse_common_location_path = staticmethod( + GeneratorEvaluationsClient.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: + GeneratorEvaluationsAsyncClient: The constructed client. + """ + return GeneratorEvaluationsClient.from_service_account_info.__func__(GeneratorEvaluationsAsyncClient, 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: + GeneratorEvaluationsAsyncClient: The constructed client. + """ + return GeneratorEvaluationsClient.from_service_account_file.__func__(GeneratorEvaluationsAsyncClient, 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 GeneratorEvaluationsClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> GeneratorEvaluationsTransport: + """Returns the transport used by the client instance. + + Returns: + GeneratorEvaluationsTransport: 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 = GeneratorEvaluationsClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + GeneratorEvaluationsTransport, + Callable[..., GeneratorEvaluationsTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the generator evaluations 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,GeneratorEvaluationsTransport,Callable[..., GeneratorEvaluationsTransport]]]): + 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 GeneratorEvaluationsTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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 = GeneratorEvaluationsClient( + 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.cloud.dialogflow_v2beta1.GeneratorEvaluationsAsyncClient`.", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "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.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "credentialsType": None, + }, + ) + + async def create_generator_evaluation( + self, + request: Optional[ + Union[gcd_generator_evaluation.CreateGeneratorEvaluationRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + generator_evaluation: Optional[ + gcd_generator_evaluation.GeneratorEvaluation + ] = 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"""Creates evaluation of a generator. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflow_v2beta1 + + async def sample_create_generator_evaluation(): + # Create a client + client = dialogflow_v2beta1.GeneratorEvaluationsAsyncClient() + + # Initialize request argument(s) + generator_evaluation = dialogflow_v2beta1.GeneratorEvaluation() + generator_evaluation.generator_evaluation_config.input_data_config.input_data_source_type = "INSIGHTS_CONVERSATIONS" + generator_evaluation.generator_evaluation_config.output_gcs_bucket_path = "output_gcs_bucket_path_value" + generator_evaluation.initial_generator.published_model = "published_model_value" + + request = dialogflow_v2beta1.CreateGeneratorEvaluationRequest( + parent="parent_value", + generator_evaluation=generator_evaluation, + ) + + # Make the request + operation = client.create_generator_evaluation(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.dialogflow_v2beta1.types.CreateGeneratorEvaluationRequest, dict]]): + The request object. Request of CreateGeneratorEvaluation. + parent (:class:`str`): + Required. The generator resource name. Format: + ``projects//locations//generators/`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + generator_evaluation (:class:`google.cloud.dialogflow_v2beta1.types.GeneratorEvaluation`): + Required. The generator evaluation to + be created. + + This corresponds to the ``generator_evaluation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value 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.cloud.dialogflow_v2beta1.types.GeneratorEvaluation` + Represents evaluation result of a generator. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, generator_evaluation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, gcd_generator_evaluation.CreateGeneratorEvaluationRequest + ): + request = gcd_generator_evaluation.CreateGeneratorEvaluationRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if generator_evaluation is not None: + request.generator_evaluation = generator_evaluation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.create_generator_evaluation + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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, + gcd_generator_evaluation.GeneratorEvaluation, + metadata_type=operations.GeneratorEvaluationOperationMetadata, + ) + + # Done; return the response. + return response + + async def get_generator_evaluation( + self, + request: Optional[ + Union[generator_evaluation.GetGeneratorEvaluationRequest, dict] + ] = None, + *, + 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]]] = (), + ) -> generator_evaluation.GeneratorEvaluation: + r"""Gets an evaluation of generator. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflow_v2beta1 + + async def sample_get_generator_evaluation(): + # Create a client + client = dialogflow_v2beta1.GeneratorEvaluationsAsyncClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.GetGeneratorEvaluationRequest( + name="name_value", + ) + + # Make the request + response = await client.get_generator_evaluation(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.dialogflow_v2beta1.types.GetGeneratorEvaluationRequest, dict]]): + The request object. Request of GetGeneratorEvaluation. + name (:class:`str`): + Required. The generator evaluation resource name. + Format: + ``projects//locations//generators//evaluations/`` + + This corresponds to the ``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.cloud.dialogflow_v2beta1.types.GeneratorEvaluation: + Represents evaluation result of a + generator. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, generator_evaluation.GetGeneratorEvaluationRequest): + request = generator_evaluation.GetGeneratorEvaluationRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = 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_generator_evaluation + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_generator_evaluations( + self, + request: Optional[ + Union[generator_evaluation.ListGeneratorEvaluationsRequest, dict] + ] = None, + *, + parent: 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.ListGeneratorEvaluationsAsyncPager: + r"""Lists evaluations of generator. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflow_v2beta1 + + async def sample_list_generator_evaluations(): + # Create a client + client = dialogflow_v2beta1.GeneratorEvaluationsAsyncClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.ListGeneratorEvaluationsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_generator_evaluations(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.dialogflow_v2beta1.types.ListGeneratorEvaluationsRequest, dict]]): + The request object. Request of ListGeneratorEvaluations. + parent (:class:`str`): + Required. The generator resource name. Format: + ``projects//locations//generators/`` + Wildcard value ``-`` is supported on generator_id to + list evaluations across all generators under same + project. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.dialogflow_v2beta1.services.generator_evaluations.pagers.ListGeneratorEvaluationsAsyncPager: + Response of ListGeneratorEvaluations. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, generator_evaluation.ListGeneratorEvaluationsRequest + ): + request = generator_evaluation.ListGeneratorEvaluationsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.list_generator_evaluations + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.ListGeneratorEvaluationsAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_generator_evaluation( + self, + request: Optional[ + Union[generator_evaluation.DeleteGeneratorEvaluationRequest, dict] + ] = None, + *, + 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]]] = (), + ) -> None: + r"""Deletes an evaluation of generator. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflow_v2beta1 + + async def sample_delete_generator_evaluation(): + # Create a client + client = dialogflow_v2beta1.GeneratorEvaluationsAsyncClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.DeleteGeneratorEvaluationRequest( + name="name_value", + ) + + # Make the request + await client.delete_generator_evaluation(request=request) + + Args: + request (Optional[Union[google.cloud.dialogflow_v2beta1.types.DeleteGeneratorEvaluationRequest, dict]]): + The request object. Request of DeleteGeneratorEvaluation. + name (:class:`str`): + Required. The generator evaluation resource name. + Format: + ``projects//locations//generators// evaluations/`` + + This corresponds to the ``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`. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, generator_evaluation.DeleteGeneratorEvaluationRequest + ): + request = generator_evaluation.DeleteGeneratorEvaluationRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.delete_generator_evaluation + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.list_operations] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 cancel_operation( + self, + request: Optional[operations_pb2.CancelOperationRequest] = 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 asynchronous cancellation on a long-running operation. + + The server makes a best effort to cancel the operation, but success + is not guaranteed. If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.CancelOperationRequest`): + The request object. Request message for + `CancelOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.CancelOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.cancel_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def get_location( + self, + request: Optional[locations_pb2.GetLocationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.Location: + r"""Gets information about a location. + + Args: + request (:class:`~.location_pb2.GetLocationRequest`): + The request object. Request message for + `GetLocation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.location_pb2.Location: + Location object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = locations_pb2.GetLocationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.get_location] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_locations( + self, + request: Optional[locations_pb2.ListLocationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.ListLocationsResponse: + r"""Lists information about the supported locations for this service. + + Args: + request (:class:`~.location_pb2.ListLocationsRequest`): + The request object. Request message for + `ListLocations` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.location_pb2.ListLocationsResponse: + Response message for ``ListLocations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = locations_pb2.ListLocationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.list_locations] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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) -> "GeneratorEvaluationsAsyncClient": + 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__ = ("GeneratorEvaluationsAsyncClient",) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/client.py new file mode 100644 index 000000000000..c3d00531d3e8 --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/client.py @@ -0,0 +1,1576 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +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.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.cloud.dialogflow_v2beta1 import gapic_version as package_version + +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.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + +from google.cloud.dialogflow_v2beta1.services.generator_evaluations import pagers +from google.cloud.dialogflow_v2beta1.types import ( + generator_evaluation as gcd_generator_evaluation, +) +from google.cloud.dialogflow_v2beta1.types import generator +from google.cloud.dialogflow_v2beta1.types import generator_evaluation +from google.cloud.dialogflow_v2beta1.types import operations + +from .transports.base import DEFAULT_CLIENT_INFO, GeneratorEvaluationsTransport +from .transports.grpc import GeneratorEvaluationsGrpcTransport +from .transports.grpc_asyncio import GeneratorEvaluationsGrpcAsyncIOTransport +from .transports.rest import GeneratorEvaluationsRestTransport + + +class GeneratorEvaluationsClientMeta(type): + """Metaclass for the GeneratorEvaluations 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[GeneratorEvaluationsTransport]] + _transport_registry["grpc"] = GeneratorEvaluationsGrpcTransport + _transport_registry["grpc_asyncio"] = GeneratorEvaluationsGrpcAsyncIOTransport + _transport_registry["rest"] = GeneratorEvaluationsRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[GeneratorEvaluationsTransport]: + """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 GeneratorEvaluationsClient(metaclass=GeneratorEvaluationsClientMeta): + """Service for managing generator evaluations.""" + + @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 = "dialogflow.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "dialogflow.{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: + GeneratorEvaluationsClient: 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: + GeneratorEvaluationsClient: 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) -> GeneratorEvaluationsTransport: + """Returns the transport used by the client instance. + + Returns: + GeneratorEvaluationsTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def generator_path( + project: str, + location: str, + generator: str, + ) -> str: + """Returns a fully-qualified generator string.""" + return "projects/{project}/locations/{location}/generators/{generator}".format( + project=project, + location=location, + generator=generator, + ) + + @staticmethod + def parse_generator_path(path: str) -> Dict[str, str]: + """Parses a generator path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/generators/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def generator_evaluation_path( + project: str, + location: str, + generator: str, + evaluation: str, + ) -> str: + """Returns a fully-qualified generator_evaluation string.""" + return "projects/{project}/locations/{location}/generators/{generator}/evaluations/{evaluation}".format( + project=project, + location=location, + generator=generator, + evaluation=evaluation, + ) + + @staticmethod + def parse_generator_evaluation_path(path: str) -> Dict[str, str]: + """Parses a generator_evaluation path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/generators/(?P.+?)/evaluations/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def tool_path( + project: str, + location: str, + tool: str, + ) -> str: + """Returns a fully-qualified tool string.""" + return "projects/{project}/locations/{location}/tools/{tool}".format( + project=project, + location=location, + tool=tool, + ) + + @staticmethod + def parse_tool_path(path: str) -> Dict[str, str]: + """Parses a tool path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/tools/(?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 = GeneratorEvaluationsClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = GeneratorEvaluationsClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = GeneratorEvaluationsClient._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 = GeneratorEvaluationsClient._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, + GeneratorEvaluationsTransport, + Callable[..., GeneratorEvaluationsTransport], + ] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the generator evaluations client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,GeneratorEvaluationsTransport,Callable[..., GeneratorEvaluationsTransport]]]): + 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 GeneratorEvaluationsTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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, + ) = GeneratorEvaluationsClient._read_environment_variables() + self._client_cert_source = GeneratorEvaluationsClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = GeneratorEvaluationsClient._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, GeneratorEvaluationsTransport) + if transport_provided: + # transport is a GeneratorEvaluationsTransport 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(GeneratorEvaluationsTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or GeneratorEvaluationsClient._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[GeneratorEvaluationsTransport], + Callable[..., GeneratorEvaluationsTransport], + ] = ( + GeneratorEvaluationsClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., GeneratorEvaluationsTransport], 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.cloud.dialogflow_v2beta1.GeneratorEvaluationsClient`.", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "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.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "credentialsType": None, + }, + ) + + def create_generator_evaluation( + self, + request: Optional[ + Union[gcd_generator_evaluation.CreateGeneratorEvaluationRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + generator_evaluation: Optional[ + gcd_generator_evaluation.GeneratorEvaluation + ] = 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"""Creates evaluation of a generator. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflow_v2beta1 + + def sample_create_generator_evaluation(): + # Create a client + client = dialogflow_v2beta1.GeneratorEvaluationsClient() + + # Initialize request argument(s) + generator_evaluation = dialogflow_v2beta1.GeneratorEvaluation() + generator_evaluation.generator_evaluation_config.input_data_config.input_data_source_type = "INSIGHTS_CONVERSATIONS" + generator_evaluation.generator_evaluation_config.output_gcs_bucket_path = "output_gcs_bucket_path_value" + generator_evaluation.initial_generator.published_model = "published_model_value" + + request = dialogflow_v2beta1.CreateGeneratorEvaluationRequest( + parent="parent_value", + generator_evaluation=generator_evaluation, + ) + + # Make the request + operation = client.create_generator_evaluation(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.dialogflow_v2beta1.types.CreateGeneratorEvaluationRequest, dict]): + The request object. Request of CreateGeneratorEvaluation. + parent (str): + Required. The generator resource name. Format: + ``projects//locations//generators/`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + generator_evaluation (google.cloud.dialogflow_v2beta1.types.GeneratorEvaluation): + Required. The generator evaluation to + be created. + + This corresponds to the ``generator_evaluation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value 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.cloud.dialogflow_v2beta1.types.GeneratorEvaluation` + Represents evaluation result of a generator. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, generator_evaluation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, gcd_generator_evaluation.CreateGeneratorEvaluationRequest + ): + request = gcd_generator_evaluation.CreateGeneratorEvaluationRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if generator_evaluation is not None: + request.generator_evaluation = generator_evaluation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.create_generator_evaluation + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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, + gcd_generator_evaluation.GeneratorEvaluation, + metadata_type=operations.GeneratorEvaluationOperationMetadata, + ) + + # Done; return the response. + return response + + def get_generator_evaluation( + self, + request: Optional[ + Union[generator_evaluation.GetGeneratorEvaluationRequest, dict] + ] = None, + *, + 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]]] = (), + ) -> generator_evaluation.GeneratorEvaluation: + r"""Gets an evaluation of generator. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflow_v2beta1 + + def sample_get_generator_evaluation(): + # Create a client + client = dialogflow_v2beta1.GeneratorEvaluationsClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.GetGeneratorEvaluationRequest( + name="name_value", + ) + + # Make the request + response = client.get_generator_evaluation(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.dialogflow_v2beta1.types.GetGeneratorEvaluationRequest, dict]): + The request object. Request of GetGeneratorEvaluation. + name (str): + Required. The generator evaluation resource name. + Format: + ``projects//locations//generators//evaluations/`` + + This corresponds to the ``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.cloud.dialogflow_v2beta1.types.GeneratorEvaluation: + Represents evaluation result of a + generator. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, generator_evaluation.GetGeneratorEvaluationRequest): + request = generator_evaluation.GetGeneratorEvaluationRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_generator_evaluation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_generator_evaluations( + self, + request: Optional[ + Union[generator_evaluation.ListGeneratorEvaluationsRequest, dict] + ] = None, + *, + parent: 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.ListGeneratorEvaluationsPager: + r"""Lists evaluations of generator. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflow_v2beta1 + + def sample_list_generator_evaluations(): + # Create a client + client = dialogflow_v2beta1.GeneratorEvaluationsClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.ListGeneratorEvaluationsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_generator_evaluations(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.dialogflow_v2beta1.types.ListGeneratorEvaluationsRequest, dict]): + The request object. Request of ListGeneratorEvaluations. + parent (str): + Required. The generator resource name. Format: + ``projects//locations//generators/`` + Wildcard value ``-`` is supported on generator_id to + list evaluations across all generators under same + project. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.dialogflow_v2beta1.services.generator_evaluations.pagers.ListGeneratorEvaluationsPager: + Response of ListGeneratorEvaluations. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, generator_evaluation.ListGeneratorEvaluationsRequest + ): + request = generator_evaluation.ListGeneratorEvaluationsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_generator_evaluations + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.ListGeneratorEvaluationsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_generator_evaluation( + self, + request: Optional[ + Union[generator_evaluation.DeleteGeneratorEvaluationRequest, dict] + ] = None, + *, + 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]]] = (), + ) -> None: + r"""Deletes an evaluation of generator. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflow_v2beta1 + + def sample_delete_generator_evaluation(): + # Create a client + client = dialogflow_v2beta1.GeneratorEvaluationsClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.DeleteGeneratorEvaluationRequest( + name="name_value", + ) + + # Make the request + client.delete_generator_evaluation(request=request) + + Args: + request (Union[google.cloud.dialogflow_v2beta1.types.DeleteGeneratorEvaluationRequest, dict]): + The request object. Request of DeleteGeneratorEvaluation. + name (str): + Required. The generator evaluation resource name. + Format: + ``projects//locations//generators// evaluations/`` + + This corresponds to the ``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`. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, generator_evaluation.DeleteGeneratorEvaluationRequest + ): + request = generator_evaluation.DeleteGeneratorEvaluationRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.delete_generator_evaluation + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def __enter__(self) -> "GeneratorEvaluationsClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_operations] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + def cancel_operation( + self, + request: Optional[operations_pb2.CancelOperationRequest] = 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 asynchronous cancellation on a long-running operation. + + The server makes a best effort to cancel the operation, but success + is not guaranteed. If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.CancelOperationRequest`): + The request object. Request message for + `CancelOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.CancelOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.cancel_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def get_location( + self, + request: Optional[locations_pb2.GetLocationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.Location: + r"""Gets information about a location. + + Args: + request (:class:`~.location_pb2.GetLocationRequest`): + The request object. Request message for + `GetLocation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.location_pb2.Location: + Location object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = locations_pb2.GetLocationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_location] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + def list_locations( + self, + request: Optional[locations_pb2.ListLocationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.ListLocationsResponse: + r"""Lists information about the supported locations for this service. + + Args: + request (:class:`~.location_pb2.ListLocationsRequest`): + The request object. Request message for + `ListLocations` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.location_pb2.ListLocationsResponse: + Response message for ``ListLocations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = locations_pb2.ListLocationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_locations] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("GeneratorEvaluationsClient",) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/pagers.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/pagers.py new file mode 100644 index 000000000000..2ef1927ec914 --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/pagers.py @@ -0,0 +1,201 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +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 + +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.cloud.dialogflow_v2beta1.types import generator_evaluation + + +class ListGeneratorEvaluationsPager: + """A pager for iterating through ``list_generator_evaluations`` requests. + + This class thinly wraps an initial + :class:`google.cloud.dialogflow_v2beta1.types.ListGeneratorEvaluationsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``generator_evaluations`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListGeneratorEvaluations`` requests and continue to iterate + through the ``generator_evaluations`` field on the + corresponding responses. + + All the usual :class:`google.cloud.dialogflow_v2beta1.types.ListGeneratorEvaluationsResponse` + 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[..., generator_evaluation.ListGeneratorEvaluationsResponse], + request: generator_evaluation.ListGeneratorEvaluationsRequest, + response: generator_evaluation.ListGeneratorEvaluationsResponse, + *, + 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.cloud.dialogflow_v2beta1.types.ListGeneratorEvaluationsRequest): + The initial request object. + response (google.cloud.dialogflow_v2beta1.types.ListGeneratorEvaluationsResponse): + 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 = generator_evaluation.ListGeneratorEvaluationsRequest(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[generator_evaluation.ListGeneratorEvaluationsResponse]: + 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[generator_evaluation.GeneratorEvaluation]: + for page in self.pages: + yield from page.generator_evaluations + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListGeneratorEvaluationsAsyncPager: + """A pager for iterating through ``list_generator_evaluations`` requests. + + This class thinly wraps an initial + :class:`google.cloud.dialogflow_v2beta1.types.ListGeneratorEvaluationsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``generator_evaluations`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListGeneratorEvaluations`` requests and continue to iterate + through the ``generator_evaluations`` field on the + corresponding responses. + + All the usual :class:`google.cloud.dialogflow_v2beta1.types.ListGeneratorEvaluationsResponse` + 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[generator_evaluation.ListGeneratorEvaluationsResponse] + ], + request: generator_evaluation.ListGeneratorEvaluationsRequest, + response: generator_evaluation.ListGeneratorEvaluationsResponse, + *, + 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.cloud.dialogflow_v2beta1.types.ListGeneratorEvaluationsRequest): + The initial request object. + response (google.cloud.dialogflow_v2beta1.types.ListGeneratorEvaluationsResponse): + 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 = generator_evaluation.ListGeneratorEvaluationsRequest(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[generator_evaluation.ListGeneratorEvaluationsResponse]: + 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[generator_evaluation.GeneratorEvaluation]: + async def async_generator(): + async for page in self.pages: + for response in page.generator_evaluations: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/transports/README.rst b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/transports/README.rst new file mode 100644 index 000000000000..d4d6f1446c83 --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`GeneratorEvaluationsTransport` is the ABC for all transports. +- public child `GeneratorEvaluationsGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `GeneratorEvaluationsGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseGeneratorEvaluationsRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `GeneratorEvaluationsRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/transports/__init__.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/transports/__init__.py new file mode 100644 index 000000000000..d8fcc5682d44 --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/transports/__init__.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 typing import Dict, Type + +from .base import GeneratorEvaluationsTransport +from .grpc import GeneratorEvaluationsGrpcTransport +from .grpc_asyncio import GeneratorEvaluationsGrpcAsyncIOTransport +from .rest import GeneratorEvaluationsRestInterceptor, GeneratorEvaluationsRestTransport + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[GeneratorEvaluationsTransport]] +_transport_registry["grpc"] = GeneratorEvaluationsGrpcTransport +_transport_registry["grpc_asyncio"] = GeneratorEvaluationsGrpcAsyncIOTransport +_transport_registry["rest"] = GeneratorEvaluationsRestTransport + +__all__ = ( + "GeneratorEvaluationsTransport", + "GeneratorEvaluationsGrpcTransport", + "GeneratorEvaluationsGrpcAsyncIOTransport", + "GeneratorEvaluationsRestTransport", + "GeneratorEvaluationsRestInterceptor", +) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/transports/base.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/transports/base.py new file mode 100644 index 000000000000..a806f99abe6d --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/transports/base.py @@ -0,0 +1,301 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, operations_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf +from google.protobuf import empty_pb2 # type: ignore + +from google.cloud.dialogflow_v2beta1 import gapic_version as package_version +from google.cloud.dialogflow_v2beta1.types import ( + generator_evaluation as gcd_generator_evaluation, +) +from google.cloud.dialogflow_v2beta1.types import generator_evaluation + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_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 GeneratorEvaluationsTransport(abc.ABC): + """Abstract transport class for GeneratorEvaluations.""" + + AUTH_SCOPES = ( + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/dialogflow", + ) + + DEFAULT_HOST: str = "dialogflow.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: 'dialogflow.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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_generator_evaluation: gapic_v1.method.wrap_method( + self.create_generator_evaluation, + default_timeout=None, + client_info=client_info, + ), + self.get_generator_evaluation: gapic_v1.method.wrap_method( + self.get_generator_evaluation, + default_timeout=None, + client_info=client_info, + ), + self.list_generator_evaluations: gapic_v1.method.wrap_method( + self.list_generator_evaluations, + default_timeout=None, + client_info=client_info, + ), + self.delete_generator_evaluation: gapic_v1.method.wrap_method( + self.delete_generator_evaluation, + default_timeout=None, + client_info=client_info, + ), + self.get_location: gapic_v1.method.wrap_method( + self.get_location, + default_timeout=None, + client_info=client_info, + ), + self.list_locations: gapic_v1.method.wrap_method( + self.list_locations, + default_timeout=None, + client_info=client_info, + ), + self.cancel_operation: gapic_v1.method.wrap_method( + self.cancel_operation, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + default_timeout=None, + client_info=client_info, + ), + self.list_operations: gapic_v1.method.wrap_method( + self.list_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 create_generator_evaluation( + self, + ) -> Callable[ + [gcd_generator_evaluation.CreateGeneratorEvaluationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def get_generator_evaluation( + self, + ) -> Callable[ + [generator_evaluation.GetGeneratorEvaluationRequest], + Union[ + generator_evaluation.GeneratorEvaluation, + Awaitable[generator_evaluation.GeneratorEvaluation], + ], + ]: + raise NotImplementedError() + + @property + def list_generator_evaluations( + self, + ) -> Callable[ + [generator_evaluation.ListGeneratorEvaluationsRequest], + Union[ + generator_evaluation.ListGeneratorEvaluationsResponse, + Awaitable[generator_evaluation.ListGeneratorEvaluationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def delete_generator_evaluation( + self, + ) -> Callable[ + [generator_evaluation.DeleteGeneratorEvaluationRequest], + Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]], + ]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[ + operations_pb2.ListOperationsResponse, + Awaitable[operations_pb2.ListOperationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def cancel_operation( + self, + ) -> Callable[[operations_pb2.CancelOperationRequest], None,]: + raise NotImplementedError() + + @property + def get_location( + self, + ) -> Callable[ + [locations_pb2.GetLocationRequest], + Union[locations_pb2.Location, Awaitable[locations_pb2.Location]], + ]: + raise NotImplementedError() + + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], + Union[ + locations_pb2.ListLocationsResponse, + Awaitable[locations_pb2.ListLocationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("GeneratorEvaluationsTransport",) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/transports/grpc.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/transports/grpc.py new file mode 100644 index 000000000000..19ef0ed41043 --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/transports/grpc.py @@ -0,0 +1,565 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json +import logging as std_logging +import pickle +from typing import Callable, Dict, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import gapic_v1, grpc_helpers, operations_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.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message +import grpc # type: ignore +import proto # type: ignore + +from google.cloud.dialogflow_v2beta1.types import ( + generator_evaluation as gcd_generator_evaluation, +) +from google.cloud.dialogflow_v2beta1.types import generator_evaluation + +from .base import DEFAULT_CLIENT_INFO, GeneratorEvaluationsTransport + +try: + from google.api_core import client_logging # 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.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "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.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class GeneratorEvaluationsGrpcTransport(GeneratorEvaluationsTransport): + """gRPC backend transport for GeneratorEvaluations. + + Service for managing generator evaluations. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call 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 = "dialogflow.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: 'dialogflow.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the 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 = "dialogflow.googleapis.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_generator_evaluation( + self, + ) -> Callable[ + [gcd_generator_evaluation.CreateGeneratorEvaluationRequest], + operations_pb2.Operation, + ]: + r"""Return a callable for the create generator evaluation method over gRPC. + + Creates evaluation of a generator. + + Returns: + Callable[[~.CreateGeneratorEvaluationRequest], + ~.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 "create_generator_evaluation" not in self._stubs: + self._stubs[ + "create_generator_evaluation" + ] = self._logged_channel.unary_unary( + "/google.cloud.dialogflow.v2beta1.GeneratorEvaluations/CreateGeneratorEvaluation", + request_serializer=gcd_generator_evaluation.CreateGeneratorEvaluationRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["create_generator_evaluation"] + + @property + def get_generator_evaluation( + self, + ) -> Callable[ + [generator_evaluation.GetGeneratorEvaluationRequest], + generator_evaluation.GeneratorEvaluation, + ]: + r"""Return a callable for the get generator evaluation method over gRPC. + + Gets an evaluation of generator. + + Returns: + Callable[[~.GetGeneratorEvaluationRequest], + ~.GeneratorEvaluation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_generator_evaluation" not in self._stubs: + self._stubs["get_generator_evaluation"] = self._logged_channel.unary_unary( + "/google.cloud.dialogflow.v2beta1.GeneratorEvaluations/GetGeneratorEvaluation", + request_serializer=generator_evaluation.GetGeneratorEvaluationRequest.serialize, + response_deserializer=generator_evaluation.GeneratorEvaluation.deserialize, + ) + return self._stubs["get_generator_evaluation"] + + @property + def list_generator_evaluations( + self, + ) -> Callable[ + [generator_evaluation.ListGeneratorEvaluationsRequest], + generator_evaluation.ListGeneratorEvaluationsResponse, + ]: + r"""Return a callable for the list generator evaluations method over gRPC. + + Lists evaluations of generator. + + Returns: + Callable[[~.ListGeneratorEvaluationsRequest], + ~.ListGeneratorEvaluationsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_generator_evaluations" not in self._stubs: + self._stubs[ + "list_generator_evaluations" + ] = self._logged_channel.unary_unary( + "/google.cloud.dialogflow.v2beta1.GeneratorEvaluations/ListGeneratorEvaluations", + request_serializer=generator_evaluation.ListGeneratorEvaluationsRequest.serialize, + response_deserializer=generator_evaluation.ListGeneratorEvaluationsResponse.deserialize, + ) + return self._stubs["list_generator_evaluations"] + + @property + def delete_generator_evaluation( + self, + ) -> Callable[ + [generator_evaluation.DeleteGeneratorEvaluationRequest], empty_pb2.Empty + ]: + r"""Return a callable for the delete generator evaluation method over gRPC. + + Deletes an evaluation of generator. + + Returns: + Callable[[~.DeleteGeneratorEvaluationRequest], + ~.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 "delete_generator_evaluation" not in self._stubs: + self._stubs[ + "delete_generator_evaluation" + ] = self._logged_channel.unary_unary( + "/google.cloud.dialogflow.v2beta1.GeneratorEvaluations/DeleteGeneratorEvaluation", + request_serializer=generator_evaluation.DeleteGeneratorEvaluationRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["delete_generator_evaluation"] + + def close(self): + self._logged_channel.close() + + @property + def cancel_operation( + self, + ) -> Callable[[operations_pb2.CancelOperationRequest], None]: + r"""Return a callable for the cancel_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "cancel_operation" not in self._stubs: + self._stubs["cancel_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/CancelOperation", + request_serializer=operations_pb2.CancelOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["cancel_operation"] + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-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_operation" not in self._stubs: + self._stubs["get_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-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_operations" not in self._stubs: + self._stubs["list_operations"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], locations_pb2.ListLocationsResponse + ]: + r"""Return a callable for the list locations method over gRPC.""" + # Generate a "stub function" on-the-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_locations" not in self._stubs: + self._stubs["list_locations"] = self._logged_channel.unary_unary( + "/google.cloud.location.Locations/ListLocations", + request_serializer=locations_pb2.ListLocationsRequest.SerializeToString, + response_deserializer=locations_pb2.ListLocationsResponse.FromString, + ) + return self._stubs["list_locations"] + + @property + def get_location( + self, + ) -> Callable[[locations_pb2.GetLocationRequest], locations_pb2.Location]: + r"""Return a callable for the list locations method over gRPC.""" + # Generate a "stub function" on-the-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_location" not in self._stubs: + self._stubs["get_location"] = self._logged_channel.unary_unary( + "/google.cloud.location.Locations/GetLocation", + request_serializer=locations_pb2.GetLocationRequest.SerializeToString, + response_deserializer=locations_pb2.Location.FromString, + ) + return self._stubs["get_location"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("GeneratorEvaluationsGrpcTransport",) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/transports/grpc_asyncio.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/transports/grpc_asyncio.py new file mode 100644 index 000000000000..12eb276ac9ec --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/transports/grpc_asyncio.py @@ -0,0 +1,629 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 json +import logging as std_logging +import pickle +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, grpc_helpers_async, operations_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message +import grpc # type: ignore +from grpc.experimental import aio # type: ignore +import proto # type: ignore + +from google.cloud.dialogflow_v2beta1.types import ( + generator_evaluation as gcd_generator_evaluation, +) +from google.cloud.dialogflow_v2beta1.types import generator_evaluation + +from .base import DEFAULT_CLIENT_INFO, GeneratorEvaluationsTransport +from .grpc import GeneratorEvaluationsGrpcTransport + +try: + from google.api_core import client_logging # 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.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "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.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class GeneratorEvaluationsGrpcAsyncIOTransport(GeneratorEvaluationsTransport): + """gRPC AsyncIO backend transport for GeneratorEvaluations. + + Service for managing generator evaluations. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call 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 = "dialogflow.googleapis.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 = "dialogflow.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: 'dialogflow.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the 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_generator_evaluation( + self, + ) -> Callable[ + [gcd_generator_evaluation.CreateGeneratorEvaluationRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the create generator evaluation method over gRPC. + + Creates evaluation of a generator. + + Returns: + Callable[[~.CreateGeneratorEvaluationRequest], + 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 "create_generator_evaluation" not in self._stubs: + self._stubs[ + "create_generator_evaluation" + ] = self._logged_channel.unary_unary( + "/google.cloud.dialogflow.v2beta1.GeneratorEvaluations/CreateGeneratorEvaluation", + request_serializer=gcd_generator_evaluation.CreateGeneratorEvaluationRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["create_generator_evaluation"] + + @property + def get_generator_evaluation( + self, + ) -> Callable[ + [generator_evaluation.GetGeneratorEvaluationRequest], + Awaitable[generator_evaluation.GeneratorEvaluation], + ]: + r"""Return a callable for the get generator evaluation method over gRPC. + + Gets an evaluation of generator. + + Returns: + Callable[[~.GetGeneratorEvaluationRequest], + Awaitable[~.GeneratorEvaluation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_generator_evaluation" not in self._stubs: + self._stubs["get_generator_evaluation"] = self._logged_channel.unary_unary( + "/google.cloud.dialogflow.v2beta1.GeneratorEvaluations/GetGeneratorEvaluation", + request_serializer=generator_evaluation.GetGeneratorEvaluationRequest.serialize, + response_deserializer=generator_evaluation.GeneratorEvaluation.deserialize, + ) + return self._stubs["get_generator_evaluation"] + + @property + def list_generator_evaluations( + self, + ) -> Callable[ + [generator_evaluation.ListGeneratorEvaluationsRequest], + Awaitable[generator_evaluation.ListGeneratorEvaluationsResponse], + ]: + r"""Return a callable for the list generator evaluations method over gRPC. + + Lists evaluations of generator. + + Returns: + Callable[[~.ListGeneratorEvaluationsRequest], + Awaitable[~.ListGeneratorEvaluationsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_generator_evaluations" not in self._stubs: + self._stubs[ + "list_generator_evaluations" + ] = self._logged_channel.unary_unary( + "/google.cloud.dialogflow.v2beta1.GeneratorEvaluations/ListGeneratorEvaluations", + request_serializer=generator_evaluation.ListGeneratorEvaluationsRequest.serialize, + response_deserializer=generator_evaluation.ListGeneratorEvaluationsResponse.deserialize, + ) + return self._stubs["list_generator_evaluations"] + + @property + def delete_generator_evaluation( + self, + ) -> Callable[ + [generator_evaluation.DeleteGeneratorEvaluationRequest], + Awaitable[empty_pb2.Empty], + ]: + r"""Return a callable for the delete generator evaluation method over gRPC. + + Deletes an evaluation of generator. + + Returns: + Callable[[~.DeleteGeneratorEvaluationRequest], + 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 "delete_generator_evaluation" not in self._stubs: + self._stubs[ + "delete_generator_evaluation" + ] = self._logged_channel.unary_unary( + "/google.cloud.dialogflow.v2beta1.GeneratorEvaluations/DeleteGeneratorEvaluation", + request_serializer=generator_evaluation.DeleteGeneratorEvaluationRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["delete_generator_evaluation"] + + 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_generator_evaluation: self._wrap_method( + self.create_generator_evaluation, + default_timeout=None, + client_info=client_info, + ), + self.get_generator_evaluation: self._wrap_method( + self.get_generator_evaluation, + default_timeout=None, + client_info=client_info, + ), + self.list_generator_evaluations: self._wrap_method( + self.list_generator_evaluations, + default_timeout=None, + client_info=client_info, + ), + self.delete_generator_evaluation: self._wrap_method( + self.delete_generator_evaluation, + default_timeout=None, + client_info=client_info, + ), + self.get_location: self._wrap_method( + self.get_location, + default_timeout=None, + client_info=client_info, + ), + self.list_locations: self._wrap_method( + self.list_locations, + default_timeout=None, + client_info=client_info, + ), + self.cancel_operation: self._wrap_method( + self.cancel_operation, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: self._wrap_method( + self.get_operation, + default_timeout=None, + client_info=client_info, + ), + self.list_operations: self._wrap_method( + self.list_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" + + @property + def cancel_operation( + self, + ) -> Callable[[operations_pb2.CancelOperationRequest], None]: + r"""Return a callable for the cancel_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "cancel_operation" not in self._stubs: + self._stubs["cancel_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/CancelOperation", + request_serializer=operations_pb2.CancelOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["cancel_operation"] + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-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_operation" not in self._stubs: + self._stubs["get_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-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_operations" not in self._stubs: + self._stubs["list_operations"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], locations_pb2.ListLocationsResponse + ]: + r"""Return a callable for the list locations method over gRPC.""" + # Generate a "stub function" on-the-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_locations" not in self._stubs: + self._stubs["list_locations"] = self._logged_channel.unary_unary( + "/google.cloud.location.Locations/ListLocations", + request_serializer=locations_pb2.ListLocationsRequest.SerializeToString, + response_deserializer=locations_pb2.ListLocationsResponse.FromString, + ) + return self._stubs["list_locations"] + + @property + def get_location( + self, + ) -> Callable[[locations_pb2.GetLocationRequest], locations_pb2.Location]: + r"""Return a callable for the list locations method over gRPC.""" + # Generate a "stub function" on-the-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_location" not in self._stubs: + self._stubs["get_location"] = self._logged_channel.unary_unary( + "/google.cloud.location.Locations/GetLocation", + request_serializer=locations_pb2.GetLocationRequest.SerializeToString, + response_deserializer=locations_pb2.Location.FromString, + ) + return self._stubs["get_location"] + + +__all__ = ("GeneratorEvaluationsGrpcAsyncIOTransport",) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/transports/rest.py new file mode 100644 index 000000000000..0704a7be091d --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/transports/rest.py @@ -0,0 +1,1853 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import gapic_v1, operations_v1, rest_helpers, rest_streaming +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.cloud.dialogflow_v2beta1.types import ( + generator_evaluation as gcd_generator_evaluation, +) +from google.cloud.dialogflow_v2beta1.types import generator_evaluation + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseGeneratorEvaluationsRestTransport + +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 = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class GeneratorEvaluationsRestInterceptor: + """Interceptor for GeneratorEvaluations. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the GeneratorEvaluationsRestTransport. + + .. code-block:: python + class MyCustomGeneratorEvaluationsInterceptor(GeneratorEvaluationsRestInterceptor): + def pre_create_generator_evaluation(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_generator_evaluation(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_generator_evaluation(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_get_generator_evaluation(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_generator_evaluation(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_generator_evaluations(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_generator_evaluations(self, response): + logging.log(f"Received response: {response}") + return response + + transport = GeneratorEvaluationsRestTransport(interceptor=MyCustomGeneratorEvaluationsInterceptor()) + client = GeneratorEvaluationsClient(transport=transport) + + + """ + + def pre_create_generator_evaluation( + self, + request: gcd_generator_evaluation.CreateGeneratorEvaluationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_generator_evaluation.CreateGeneratorEvaluationRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for create_generator_evaluation + + Override in a subclass to manipulate the request or metadata + before they are sent to the GeneratorEvaluations server. + """ + return request, metadata + + def post_create_generator_evaluation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for create_generator_evaluation + + DEPRECATED. Please use the `post_create_generator_evaluation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the GeneratorEvaluations server but before + it is returned to user code. This `post_create_generator_evaluation` interceptor runs + before the `post_create_generator_evaluation_with_metadata` interceptor. + """ + return response + + def post_create_generator_evaluation_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_generator_evaluation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the GeneratorEvaluations server but before it is returned to user code. + + We recommend only using this `post_create_generator_evaluation_with_metadata` + interceptor in new development instead of the `post_create_generator_evaluation` interceptor. + When both interceptors are used, this `post_create_generator_evaluation_with_metadata` interceptor runs after the + `post_create_generator_evaluation` interceptor. The (possibly modified) response returned by + `post_create_generator_evaluation` will be passed to + `post_create_generator_evaluation_with_metadata`. + """ + return response, metadata + + def pre_delete_generator_evaluation( + self, + request: generator_evaluation.DeleteGeneratorEvaluationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + generator_evaluation.DeleteGeneratorEvaluationRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for delete_generator_evaluation + + Override in a subclass to manipulate the request or metadata + before they are sent to the GeneratorEvaluations server. + """ + return request, metadata + + def pre_get_generator_evaluation( + self, + request: generator_evaluation.GetGeneratorEvaluationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + generator_evaluation.GetGeneratorEvaluationRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for get_generator_evaluation + + Override in a subclass to manipulate the request or metadata + before they are sent to the GeneratorEvaluations server. + """ + return request, metadata + + def post_get_generator_evaluation( + self, response: generator_evaluation.GeneratorEvaluation + ) -> generator_evaluation.GeneratorEvaluation: + """Post-rpc interceptor for get_generator_evaluation + + DEPRECATED. Please use the `post_get_generator_evaluation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the GeneratorEvaluations server but before + it is returned to user code. This `post_get_generator_evaluation` interceptor runs + before the `post_get_generator_evaluation_with_metadata` interceptor. + """ + return response + + def post_get_generator_evaluation_with_metadata( + self, + response: generator_evaluation.GeneratorEvaluation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + generator_evaluation.GeneratorEvaluation, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for get_generator_evaluation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the GeneratorEvaluations server but before it is returned to user code. + + We recommend only using this `post_get_generator_evaluation_with_metadata` + interceptor in new development instead of the `post_get_generator_evaluation` interceptor. + When both interceptors are used, this `post_get_generator_evaluation_with_metadata` interceptor runs after the + `post_get_generator_evaluation` interceptor. The (possibly modified) response returned by + `post_get_generator_evaluation` will be passed to + `post_get_generator_evaluation_with_metadata`. + """ + return response, metadata + + def pre_list_generator_evaluations( + self, + request: generator_evaluation.ListGeneratorEvaluationsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + generator_evaluation.ListGeneratorEvaluationsRequest, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Pre-rpc interceptor for list_generator_evaluations + + Override in a subclass to manipulate the request or metadata + before they are sent to the GeneratorEvaluations server. + """ + return request, metadata + + def post_list_generator_evaluations( + self, response: generator_evaluation.ListGeneratorEvaluationsResponse + ) -> generator_evaluation.ListGeneratorEvaluationsResponse: + """Post-rpc interceptor for list_generator_evaluations + + DEPRECATED. Please use the `post_list_generator_evaluations_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the GeneratorEvaluations server but before + it is returned to user code. This `post_list_generator_evaluations` interceptor runs + before the `post_list_generator_evaluations_with_metadata` interceptor. + """ + return response + + def post_list_generator_evaluations_with_metadata( + self, + response: generator_evaluation.ListGeneratorEvaluationsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + generator_evaluation.ListGeneratorEvaluationsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_generator_evaluations + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the GeneratorEvaluations server but before it is returned to user code. + + We recommend only using this `post_list_generator_evaluations_with_metadata` + interceptor in new development instead of the `post_list_generator_evaluations` interceptor. + When both interceptors are used, this `post_list_generator_evaluations_with_metadata` interceptor runs after the + `post_list_generator_evaluations` interceptor. The (possibly modified) response returned by + `post_list_generator_evaluations` will be passed to + `post_list_generator_evaluations_with_metadata`. + """ + return response, metadata + + def pre_get_location( + self, + request: locations_pb2.GetLocationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + locations_pb2.GetLocationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_location + + Override in a subclass to manipulate the request or metadata + before they are sent to the GeneratorEvaluations server. + """ + return request, metadata + + def post_get_location( + self, response: locations_pb2.Location + ) -> locations_pb2.Location: + """Post-rpc interceptor for get_location + + Override in a subclass to manipulate the response + after it is returned by the GeneratorEvaluations server but before + it is returned to user code. + """ + return response + + def pre_list_locations( + self, + request: locations_pb2.ListLocationsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + locations_pb2.ListLocationsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for list_locations + + Override in a subclass to manipulate the request or metadata + before they are sent to the GeneratorEvaluations server. + """ + return request, metadata + + def post_list_locations( + self, response: locations_pb2.ListLocationsResponse + ) -> locations_pb2.ListLocationsResponse: + """Post-rpc interceptor for list_locations + + Override in a subclass to manipulate the response + after it is returned by the GeneratorEvaluations server but before + it is returned to user code. + """ + return response + + def pre_cancel_operation( + self, + request: operations_pb2.CancelOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.CancelOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for cancel_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the GeneratorEvaluations server. + """ + return request, metadata + + def post_cancel_operation(self, response: None) -> None: + """Post-rpc interceptor for cancel_operation + + Override in a subclass to manipulate the response + after it is returned by the GeneratorEvaluations server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the GeneratorEvaluations server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the GeneratorEvaluations server but before + it is returned to user code. + """ + return response + + def pre_list_operations( + self, + request: operations_pb2.ListOperationsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.ListOperationsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the GeneratorEvaluations server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the GeneratorEvaluations server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class GeneratorEvaluationsRestStub: + _session: AuthorizedSession + _host: str + _interceptor: GeneratorEvaluationsRestInterceptor + + +class GeneratorEvaluationsRestTransport(_BaseGeneratorEvaluationsRestTransport): + """REST backend synchronous transport for GeneratorEvaluations. + + Service for managing generator evaluations. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "dialogflow.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[GeneratorEvaluationsRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'dialogflow.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or GeneratorEvaluationsRestInterceptor() + self._prep_wrapped_messages(client_info) + + @property + def operations_client(self) -> operations_v1.AbstractOperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Only create a new client if we do not already have one. + if self._operations_client is None: + http_options: Dict[str, List[Dict[str, str]]] = { + "google.longrunning.Operations.CancelOperation": [ + { + "method": "post", + "uri": "/v2beta1/{name=projects/*/operations/*}:cancel", + }, + { + "method": "post", + "uri": "/v2beta1/{name=projects/*/locations/*/operations/*}:cancel", + }, + ], + "google.longrunning.Operations.GetOperation": [ + { + "method": "get", + "uri": "/v2beta1/{name=projects/*/operations/*}", + }, + { + "method": "get", + "uri": "/v2beta1/{name=projects/*/locations/*/operations/*}", + }, + ], + "google.longrunning.Operations.ListOperations": [ + { + "method": "get", + "uri": "/v2beta1/{name=projects/*}/operations", + }, + { + "method": "get", + "uri": "/v2beta1/{name=projects/*/locations/*}/operations", + }, + ], + } + + rest_transport = operations_v1.OperationsRestTransport( + host=self._host, + # use the credentials which are saved + credentials=self._credentials, + scopes=self._scopes, + http_options=http_options, + path_prefix="v2beta1", + ) + + self._operations_client = operations_v1.AbstractOperationsClient( + transport=rest_transport + ) + + # Return the client from cache. + return self._operations_client + + class _CreateGeneratorEvaluation( + _BaseGeneratorEvaluationsRestTransport._BaseCreateGeneratorEvaluation, + GeneratorEvaluationsRestStub, + ): + def __hash__(self): + return hash("GeneratorEvaluationsRestTransport.CreateGeneratorEvaluation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: gcd_generator_evaluation.CreateGeneratorEvaluationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the create generator + evaluation method over HTTP. + + Args: + request (~.gcd_generator_evaluation.CreateGeneratorEvaluationRequest): + The request object. Request of CreateGeneratorEvaluation. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options = ( + _BaseGeneratorEvaluationsRestTransport._BaseCreateGeneratorEvaluation._get_http_options() + ) + + request, metadata = self._interceptor.pre_create_generator_evaluation( + request, metadata + ) + transcoded_request = _BaseGeneratorEvaluationsRestTransport._BaseCreateGeneratorEvaluation._get_transcoded_request( + http_options, request + ) + + body = _BaseGeneratorEvaluationsRestTransport._BaseCreateGeneratorEvaluation._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = _BaseGeneratorEvaluationsRestTransport._BaseCreateGeneratorEvaluation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.dialogflow_v2beta1.GeneratorEvaluationsClient.CreateGeneratorEvaluation", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "rpcName": "CreateGeneratorEvaluation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = GeneratorEvaluationsRestTransport._CreateGeneratorEvaluation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_generator_evaluation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_generator_evaluation_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.dialogflow_v2beta1.GeneratorEvaluationsClient.create_generator_evaluation", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "rpcName": "CreateGeneratorEvaluation", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _DeleteGeneratorEvaluation( + _BaseGeneratorEvaluationsRestTransport._BaseDeleteGeneratorEvaluation, + GeneratorEvaluationsRestStub, + ): + def __hash__(self): + return hash("GeneratorEvaluationsRestTransport.DeleteGeneratorEvaluation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: generator_evaluation.DeleteGeneratorEvaluationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + r"""Call the delete generator + evaluation method over HTTP. + + Args: + request (~.generator_evaluation.DeleteGeneratorEvaluationRequest): + The request object. Request of DeleteGeneratorEvaluation. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + + http_options = ( + _BaseGeneratorEvaluationsRestTransport._BaseDeleteGeneratorEvaluation._get_http_options() + ) + + request, metadata = self._interceptor.pre_delete_generator_evaluation( + request, metadata + ) + transcoded_request = _BaseGeneratorEvaluationsRestTransport._BaseDeleteGeneratorEvaluation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseGeneratorEvaluationsRestTransport._BaseDeleteGeneratorEvaluation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.dialogflow_v2beta1.GeneratorEvaluationsClient.DeleteGeneratorEvaluation", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "rpcName": "DeleteGeneratorEvaluation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = GeneratorEvaluationsRestTransport._DeleteGeneratorEvaluation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _GetGeneratorEvaluation( + _BaseGeneratorEvaluationsRestTransport._BaseGetGeneratorEvaluation, + GeneratorEvaluationsRestStub, + ): + def __hash__(self): + return hash("GeneratorEvaluationsRestTransport.GetGeneratorEvaluation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: generator_evaluation.GetGeneratorEvaluationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> generator_evaluation.GeneratorEvaluation: + r"""Call the get generator evaluation method over HTTP. + + Args: + request (~.generator_evaluation.GetGeneratorEvaluationRequest): + The request object. Request of GetGeneratorEvaluation. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.generator_evaluation.GeneratorEvaluation: + Represents evaluation result of a + generator. + + """ + + http_options = ( + _BaseGeneratorEvaluationsRestTransport._BaseGetGeneratorEvaluation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_generator_evaluation( + request, metadata + ) + transcoded_request = _BaseGeneratorEvaluationsRestTransport._BaseGetGeneratorEvaluation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseGeneratorEvaluationsRestTransport._BaseGetGeneratorEvaluation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.dialogflow_v2beta1.GeneratorEvaluationsClient.GetGeneratorEvaluation", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "rpcName": "GetGeneratorEvaluation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ( + GeneratorEvaluationsRestTransport._GetGeneratorEvaluation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = generator_evaluation.GeneratorEvaluation() + pb_resp = generator_evaluation.GeneratorEvaluation.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_generator_evaluation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_generator_evaluation_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = generator_evaluation.GeneratorEvaluation.to_json( + response + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.dialogflow_v2beta1.GeneratorEvaluationsClient.get_generator_evaluation", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "rpcName": "GetGeneratorEvaluation", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListGeneratorEvaluations( + _BaseGeneratorEvaluationsRestTransport._BaseListGeneratorEvaluations, + GeneratorEvaluationsRestStub, + ): + def __hash__(self): + return hash("GeneratorEvaluationsRestTransport.ListGeneratorEvaluations") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: generator_evaluation.ListGeneratorEvaluationsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> generator_evaluation.ListGeneratorEvaluationsResponse: + r"""Call the list generator + evaluations method over HTTP. + + Args: + request (~.generator_evaluation.ListGeneratorEvaluationsRequest): + The request object. Request of ListGeneratorEvaluations. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.generator_evaluation.ListGeneratorEvaluationsResponse: + Response of ListGeneratorEvaluations. + """ + + http_options = ( + _BaseGeneratorEvaluationsRestTransport._BaseListGeneratorEvaluations._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_generator_evaluations( + request, metadata + ) + transcoded_request = _BaseGeneratorEvaluationsRestTransport._BaseListGeneratorEvaluations._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseGeneratorEvaluationsRestTransport._BaseListGeneratorEvaluations._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.dialogflow_v2beta1.GeneratorEvaluationsClient.ListGeneratorEvaluations", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "rpcName": "ListGeneratorEvaluations", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = GeneratorEvaluationsRestTransport._ListGeneratorEvaluations._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = generator_evaluation.ListGeneratorEvaluationsResponse() + pb_resp = generator_evaluation.ListGeneratorEvaluationsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_generator_evaluations(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_generator_evaluations_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = ( + generator_evaluation.ListGeneratorEvaluationsResponse.to_json( + response + ) + ) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.dialogflow_v2beta1.GeneratorEvaluationsClient.list_generator_evaluations", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "rpcName": "ListGeneratorEvaluations", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def create_generator_evaluation( + self, + ) -> Callable[ + [gcd_generator_evaluation.CreateGeneratorEvaluationRequest], + operations_pb2.Operation, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateGeneratorEvaluation(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_generator_evaluation( + self, + ) -> Callable[ + [generator_evaluation.DeleteGeneratorEvaluationRequest], empty_pb2.Empty + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteGeneratorEvaluation(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_generator_evaluation( + self, + ) -> Callable[ + [generator_evaluation.GetGeneratorEvaluationRequest], + generator_evaluation.GeneratorEvaluation, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetGeneratorEvaluation(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_generator_evaluations( + self, + ) -> Callable[ + [generator_evaluation.ListGeneratorEvaluationsRequest], + generator_evaluation.ListGeneratorEvaluationsResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListGeneratorEvaluations(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_location(self): + return self._GetLocation(self._session, self._host, self._interceptor) # type: ignore + + class _GetLocation( + _BaseGeneratorEvaluationsRestTransport._BaseGetLocation, + GeneratorEvaluationsRestStub, + ): + def __hash__(self): + return hash("GeneratorEvaluationsRestTransport.GetLocation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: locations_pb2.GetLocationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.Location: + r"""Call the get location method over HTTP. + + Args: + request (locations_pb2.GetLocationRequest): + The request object for GetLocation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + locations_pb2.Location: Response from GetLocation method. + """ + + http_options = ( + _BaseGeneratorEvaluationsRestTransport._BaseGetLocation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_location(request, metadata) + transcoded_request = _BaseGeneratorEvaluationsRestTransport._BaseGetLocation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseGeneratorEvaluationsRestTransport._BaseGetLocation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.dialogflow_v2beta1.GeneratorEvaluationsClient.GetLocation", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "rpcName": "GetLocation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = GeneratorEvaluationsRestTransport._GetLocation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = locations_pb2.Location() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_location(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.dialogflow_v2beta1.GeneratorEvaluationsAsyncClient.GetLocation", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "rpcName": "GetLocation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def list_locations(self): + return self._ListLocations(self._session, self._host, self._interceptor) # type: ignore + + class _ListLocations( + _BaseGeneratorEvaluationsRestTransport._BaseListLocations, + GeneratorEvaluationsRestStub, + ): + def __hash__(self): + return hash("GeneratorEvaluationsRestTransport.ListLocations") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: locations_pb2.ListLocationsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.ListLocationsResponse: + r"""Call the list locations method over HTTP. + + Args: + request (locations_pb2.ListLocationsRequest): + The request object for ListLocations method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + locations_pb2.ListLocationsResponse: Response from ListLocations method. + """ + + http_options = ( + _BaseGeneratorEvaluationsRestTransport._BaseListLocations._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_locations(request, metadata) + transcoded_request = _BaseGeneratorEvaluationsRestTransport._BaseListLocations._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseGeneratorEvaluationsRestTransport._BaseListLocations._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.dialogflow_v2beta1.GeneratorEvaluationsClient.ListLocations", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "rpcName": "ListLocations", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = GeneratorEvaluationsRestTransport._ListLocations._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = locations_pb2.ListLocationsResponse() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_list_locations(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.dialogflow_v2beta1.GeneratorEvaluationsAsyncClient.ListLocations", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "rpcName": "ListLocations", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def cancel_operation(self): + return self._CancelOperation(self._session, self._host, self._interceptor) # type: ignore + + class _CancelOperation( + _BaseGeneratorEvaluationsRestTransport._BaseCancelOperation, + GeneratorEvaluationsRestStub, + ): + def __hash__(self): + return hash("GeneratorEvaluationsRestTransport.CancelOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.CancelOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Call the cancel operation method over HTTP. + + Args: + request (operations_pb2.CancelOperationRequest): + The request object for CancelOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + + http_options = ( + _BaseGeneratorEvaluationsRestTransport._BaseCancelOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_cancel_operation( + request, metadata + ) + transcoded_request = _BaseGeneratorEvaluationsRestTransport._BaseCancelOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseGeneratorEvaluationsRestTransport._BaseCancelOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.dialogflow_v2beta1.GeneratorEvaluationsClient.CancelOperation", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "rpcName": "CancelOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = GeneratorEvaluationsRestTransport._CancelOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + return self._interceptor.post_cancel_operation(None) + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation( + _BaseGeneratorEvaluationsRestTransport._BaseGetOperation, + GeneratorEvaluationsRestStub, + ): + def __hash__(self): + return hash("GeneratorEvaluationsRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = ( + _BaseGeneratorEvaluationsRestTransport._BaseGetOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = _BaseGeneratorEvaluationsRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseGeneratorEvaluationsRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.dialogflow_v2beta1.GeneratorEvaluationsClient.GetOperation", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = GeneratorEvaluationsRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.dialogflow_v2beta1.GeneratorEvaluationsAsyncClient.GetOperation", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations( + _BaseGeneratorEvaluationsRestTransport._BaseListOperations, + GeneratorEvaluationsRestStub, + ): + def __hash__(self): + return hash("GeneratorEvaluationsRestTransport.ListOperations") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.ListOperationsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.ListOperationsResponse: Response from ListOperations method. + """ + + http_options = ( + _BaseGeneratorEvaluationsRestTransport._BaseListOperations._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + transcoded_request = _BaseGeneratorEvaluationsRestTransport._BaseListOperations._get_transcoded_request( + http_options, request + ) + + # Jsonify the query params + query_params = _BaseGeneratorEvaluationsRestTransport._BaseListOperations._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.dialogflow_v2beta1.GeneratorEvaluationsClient.ListOperations", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "rpcName": "ListOperations", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = GeneratorEvaluationsRestTransport._ListOperations._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_list_operations(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.dialogflow_v2beta1.GeneratorEvaluationsAsyncClient.ListOperations", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "rpcName": "ListOperations", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("GeneratorEvaluationsRestTransport",) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/transports/rest_base.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/transports/rest_base.py new file mode 100644 index 000000000000..6203e553a7ca --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generator_evaluations/transports/rest_base.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 json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import json_format + +from google.cloud.dialogflow_v2beta1.types import ( + generator_evaluation as gcd_generator_evaluation, +) +from google.cloud.dialogflow_v2beta1.types import generator_evaluation + +from .base import DEFAULT_CLIENT_INFO, GeneratorEvaluationsTransport + + +class _BaseGeneratorEvaluationsRestTransport(GeneratorEvaluationsTransport): + """Base REST backend transport for GeneratorEvaluations. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "dialogflow.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'dialogflow.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseCreateGeneratorEvaluation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2beta1/{parent=projects/*/locations/*/generators/*}/evaluations", + "body": "generator_evaluation", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = gcd_generator_evaluation.CreateGeneratorEvaluationRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseGeneratorEvaluationsRestTransport._BaseCreateGeneratorEvaluation._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseDeleteGeneratorEvaluation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v2beta1/{name=projects/*/locations/*/generators/*/evaluations/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = generator_evaluation.DeleteGeneratorEvaluationRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseGeneratorEvaluationsRestTransport._BaseDeleteGeneratorEvaluation._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetGeneratorEvaluation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2beta1/{name=projects/*/locations/*/generators/*/evaluations/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = generator_evaluation.GetGeneratorEvaluationRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseGeneratorEvaluationsRestTransport._BaseGetGeneratorEvaluation._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListGeneratorEvaluations: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2beta1/{parent=projects/*/locations/*/generators/*}/evaluations", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = generator_evaluation.ListGeneratorEvaluationsRequest.pb( + request + ) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseGeneratorEvaluationsRestTransport._BaseListGeneratorEvaluations._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetLocation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2beta1/{name=projects/*/locations/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseListLocations: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2beta1/{name=projects/*}/locations", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseCancelOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2beta1/{name=projects/*/operations/*}:cancel", + }, + { + "method": "post", + "uri": "/v2beta1/{name=projects/*/locations/*/operations/*}:cancel", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2beta1/{name=projects/*/operations/*}", + }, + { + "method": "get", + "uri": "/v2beta1/{name=projects/*/locations/*/operations/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseListOperations: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2beta1/{name=projects/*}/operations", + }, + { + "method": "get", + "uri": "/v2beta1/{name=projects/*/locations/*}/operations", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseGeneratorEvaluationsRestTransport",) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generators/async_client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generators/async_client.py index 7288c10541f5..5b1931d1aa6f 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generators/async_client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generators/async_client.py @@ -86,6 +86,8 @@ class GeneratorsAsyncClient: generator_path = staticmethod(GeneratorsClient.generator_path) parse_generator_path = staticmethod(GeneratorsClient.parse_generator_path) + tool_path = staticmethod(GeneratorsClient.tool_path) + parse_tool_path = staticmethod(GeneratorsClient.parse_tool_path) common_billing_account_path = staticmethod( GeneratorsClient.common_billing_account_path ) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generators/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generators/client.py index 240633ac4c9d..3d22bd85dcff 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generators/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generators/client.py @@ -227,6 +227,28 @@ def parse_generator_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def tool_path( + project: str, + location: str, + tool: str, + ) -> str: + """Returns a fully-qualified tool string.""" + return "projects/{project}/locations/{location}/tools/{tool}".format( + project=project, + location=location, + tool=tool, + ) + + @staticmethod + def parse_tool_path(path: str) -> Dict[str, str]: + """Parses a tool path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/tools/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def common_billing_account_path( billing_account: str, diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/async_client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/async_client.py index 7acd61ccf108..14a075c3e7e1 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/async_client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/async_client.py @@ -103,6 +103,8 @@ class ParticipantsAsyncClient: parse_session_entity_type_path = staticmethod( ParticipantsClient.parse_session_entity_type_path ) + tool_path = staticmethod(ParticipantsClient.tool_path) + parse_tool_path = staticmethod(ParticipantsClient.parse_tool_path) common_billing_account_path = staticmethod( ParticipantsClient.common_billing_account_path ) @@ -1113,6 +1115,102 @@ def request_generator(): # Done; return the response. return response + def bidi_streaming_analyze_content( + self, + requests: Optional[ + AsyncIterator[participant.BidiStreamingAnalyzeContentRequest] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> Awaitable[AsyncIterable[participant.BidiStreamingAnalyzeContentResponse]]: + r"""Bidirectional endless streaming version of + [StreamingAnalyzeContent][google.cloud.dialogflow.v2beta1.Participants.StreamingAnalyzeContent]. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflow_v2beta1 + + async def sample_bidi_streaming_analyze_content(): + # Create a client + client = dialogflow_v2beta1.ParticipantsAsyncClient() + + # Initialize request argument(s) + config = dialogflow_v2beta1.Config() + config.voice_session_config.input_audio_encoding = "AUDIO_ENCODING_ALAW" + config.voice_session_config.input_audio_sample_rate_hertz = 3097 + config.voice_session_config.output_audio_encoding = "OUTPUT_AUDIO_ENCODING_ALAW" + config.voice_session_config.output_audio_sample_rate_hertz = 3226 + config.participant = "participant_value" + + request = dialogflow_v2beta1.BidiStreamingAnalyzeContentRequest( + config=config, + ) + + # This method expects an iterator which contains + # 'dialogflow_v2beta1.BidiStreamingAnalyzeContentRequest' objects + # Here we create a generator that yields a single `request` for + # demonstrative purposes. + requests = [request] + + def request_generator(): + for request in requests: + yield request + + # Make the request + stream = await client.bidi_streaming_analyze_content(requests=request_generator()) + + # Handle the response + async for response in stream: + print(response) + + Args: + requests (AsyncIterator[`google.cloud.dialogflow_v2beta1.types.BidiStreamingAnalyzeContentRequest`]): + The request object AsyncIterator. The request message for + [Participants.BidiStreamingAnalyzeContent][google.cloud.dialogflow.v2beta1.Participants.BidiStreamingAnalyzeContent]. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.cloud.dialogflow_v2beta1.types.BidiStreamingAnalyzeContentResponse]: + The response message for + [Participants.BidiStreamingAnalyzeContent][google.cloud.dialogflow.v2beta1.Participants.BidiStreamingAnalyzeContent]. + + """ + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.bidi_streaming_analyze_content + ] + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = rpc( + requests, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + async def suggest_articles( self, request: Optional[Union[participant.SuggestArticlesRequest, dict]] = None, diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/client.py index 20cf8582aaa9..ad901b5d537e 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/client.py @@ -374,6 +374,28 @@ def parse_session_entity_type_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def tool_path( + project: str, + location: str, + tool: str, + ) -> str: + """Returns a fully-qualified tool string.""" + return "projects/{project}/locations/{location}/tools/{tool}".format( + project=project, + location=location, + tool=tool, + ) + + @staticmethod + def parse_tool_path(path: str) -> Dict[str, str]: + """Parses a tool path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/tools/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def common_billing_account_path( billing_account: str, @@ -1648,6 +1670,102 @@ def request_generator(): # Done; return the response. return response + def bidi_streaming_analyze_content( + self, + requests: Optional[ + Iterator[participant.BidiStreamingAnalyzeContentRequest] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> Iterable[participant.BidiStreamingAnalyzeContentResponse]: + r"""Bidirectional endless streaming version of + [StreamingAnalyzeContent][google.cloud.dialogflow.v2beta1.Participants.StreamingAnalyzeContent]. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflow_v2beta1 + + def sample_bidi_streaming_analyze_content(): + # Create a client + client = dialogflow_v2beta1.ParticipantsClient() + + # Initialize request argument(s) + config = dialogflow_v2beta1.Config() + config.voice_session_config.input_audio_encoding = "AUDIO_ENCODING_ALAW" + config.voice_session_config.input_audio_sample_rate_hertz = 3097 + config.voice_session_config.output_audio_encoding = "OUTPUT_AUDIO_ENCODING_ALAW" + config.voice_session_config.output_audio_sample_rate_hertz = 3226 + config.participant = "participant_value" + + request = dialogflow_v2beta1.BidiStreamingAnalyzeContentRequest( + config=config, + ) + + # This method expects an iterator which contains + # 'dialogflow_v2beta1.BidiStreamingAnalyzeContentRequest' objects + # Here we create a generator that yields a single `request` for + # demonstrative purposes. + requests = [request] + + def request_generator(): + for request in requests: + yield request + + # Make the request + stream = client.bidi_streaming_analyze_content(requests=request_generator()) + + # Handle the response + for response in stream: + print(response) + + Args: + requests (Iterator[google.cloud.dialogflow_v2beta1.types.BidiStreamingAnalyzeContentRequest]): + The request object iterator. The request message for + [Participants.BidiStreamingAnalyzeContent][google.cloud.dialogflow.v2beta1.Participants.BidiStreamingAnalyzeContent]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.cloud.dialogflow_v2beta1.types.BidiStreamingAnalyzeContentResponse]: + The response message for + [Participants.BidiStreamingAnalyzeContent][google.cloud.dialogflow.v2beta1.Participants.BidiStreamingAnalyzeContent]. + + """ + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.bidi_streaming_analyze_content + ] + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + requests, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + def suggest_articles( self, request: Optional[Union[participant.SuggestArticlesRequest, dict]] = None, diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/base.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/base.py index 07128fe4d8b3..9326bbda63cf 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/base.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/base.py @@ -178,6 +178,18 @@ def _prep_wrapped_messages(self, client_info): default_timeout=220.0, client_info=client_info, ), + self.bidi_streaming_analyze_content: gapic_v1.method.wrap_method( + self.bidi_streaming_analyze_content, + default_retry=retries.Retry( + initial=0.1, + maximum=60.0, + multiplier=1.3, + predicate=retries.if_exception_type(), + deadline=1800.0, + ), + default_timeout=1800.0, + client_info=client_info, + ), self.suggest_articles: gapic_v1.method.wrap_method( self.suggest_articles, default_timeout=None, @@ -307,6 +319,18 @@ def streaming_analyze_content( ]: raise NotImplementedError() + @property + def bidi_streaming_analyze_content( + self, + ) -> Callable[ + [participant.BidiStreamingAnalyzeContentRequest], + Union[ + participant.BidiStreamingAnalyzeContentResponse, + Awaitable[participant.BidiStreamingAnalyzeContentResponse], + ], + ]: + raise NotImplementedError() + @property def suggest_articles( self, diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/grpc.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/grpc.py index 02a3c0b39ad3..e33baa63c4ba 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/grpc.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/grpc.py @@ -514,6 +514,38 @@ def streaming_analyze_content( ) return self._stubs["streaming_analyze_content"] + @property + def bidi_streaming_analyze_content( + self, + ) -> Callable[ + [participant.BidiStreamingAnalyzeContentRequest], + participant.BidiStreamingAnalyzeContentResponse, + ]: + r"""Return a callable for the bidi streaming analyze content method over gRPC. + + Bidirectional endless streaming version of + [StreamingAnalyzeContent][google.cloud.dialogflow.v2beta1.Participants.StreamingAnalyzeContent]. + + Returns: + Callable[[~.BidiStreamingAnalyzeContentRequest], + ~.BidiStreamingAnalyzeContentResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "bidi_streaming_analyze_content" not in self._stubs: + self._stubs[ + "bidi_streaming_analyze_content" + ] = self._logged_channel.stream_stream( + "/google.cloud.dialogflow.v2beta1.Participants/BidiStreamingAnalyzeContent", + request_serializer=participant.BidiStreamingAnalyzeContentRequest.serialize, + response_deserializer=participant.BidiStreamingAnalyzeContentResponse.deserialize, + ) + return self._stubs["bidi_streaming_analyze_content"] + @property def suggest_articles( self, diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/grpc_asyncio.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/grpc_asyncio.py index f104d00e8573..1a1cf549ae4e 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/grpc_asyncio.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/grpc_asyncio.py @@ -528,6 +528,38 @@ def streaming_analyze_content( ) return self._stubs["streaming_analyze_content"] + @property + def bidi_streaming_analyze_content( + self, + ) -> Callable[ + [participant.BidiStreamingAnalyzeContentRequest], + Awaitable[participant.BidiStreamingAnalyzeContentResponse], + ]: + r"""Return a callable for the bidi streaming analyze content method over gRPC. + + Bidirectional endless streaming version of + [StreamingAnalyzeContent][google.cloud.dialogflow.v2beta1.Participants.StreamingAnalyzeContent]. + + Returns: + Callable[[~.BidiStreamingAnalyzeContentRequest], + Awaitable[~.BidiStreamingAnalyzeContentResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "bidi_streaming_analyze_content" not in self._stubs: + self._stubs[ + "bidi_streaming_analyze_content" + ] = self._logged_channel.stream_stream( + "/google.cloud.dialogflow.v2beta1.Participants/BidiStreamingAnalyzeContent", + request_serializer=participant.BidiStreamingAnalyzeContentRequest.serialize, + response_deserializer=participant.BidiStreamingAnalyzeContentResponse.deserialize, + ) + return self._stubs["bidi_streaming_analyze_content"] + @property def suggest_articles( self, @@ -788,6 +820,18 @@ def _prep_wrapped_messages(self, client_info): default_timeout=220.0, client_info=client_info, ), + self.bidi_streaming_analyze_content: self._wrap_method( + self.bidi_streaming_analyze_content, + default_retry=retries.AsyncRetry( + initial=0.1, + maximum=60.0, + multiplier=1.3, + predicate=retries.if_exception_type(), + deadline=1800.0, + ), + default_timeout=1800.0, + client_info=client_info, + ), self.suggest_articles: self._wrap_method( self.suggest_articles, default_timeout=None, diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/rest.py index 8d8dd50ffb60..a3471662568a 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/rest.py @@ -1084,6 +1084,25 @@ def __call__( ) return resp + class _BidiStreamingAnalyzeContent( + _BaseParticipantsRestTransport._BaseBidiStreamingAnalyzeContent, + ParticipantsRestStub, + ): + def __hash__(self): + return hash("ParticipantsRestTransport.BidiStreamingAnalyzeContent") + + def __call__( + self, + request: participant.BidiStreamingAnalyzeContentRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> rest_streaming.ResponseIterator: + raise NotImplementedError( + "Method BidiStreamingAnalyzeContent is not available over REST transport" + ) + class _CompileSuggestion( _BaseParticipantsRestTransport._BaseCompileSuggestion, ParticipantsRestStub ): @@ -2657,6 +2676,17 @@ def analyze_content( # In C++ this would require a dynamic_cast return self._AnalyzeContent(self._session, self._host, self._interceptor) # type: ignore + @property + def bidi_streaming_analyze_content( + self, + ) -> Callable[ + [participant.BidiStreamingAnalyzeContentRequest], + participant.BidiStreamingAnalyzeContentResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._BidiStreamingAnalyzeContent(self._session, self._host, self._interceptor) # type: ignore + @property def compile_suggestion( self, diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/rest_base.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/rest_base.py index 523a9e513767..99a23252d8ae 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/rest_base.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/rest_base.py @@ -152,6 +152,10 @@ def _get_query_params_json(transcoded_request): query_params["$alt"] = "json;enum-encoding=int" return query_params + class _BaseBidiStreamingAnalyzeContent: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + class _BaseCompileSuggestion: def __hash__(self): # pragma: NO COVER return NotImplementedError("__hash__ must be implemented.") diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/__init__.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/__init__.py new file mode 100644 index 000000000000..ca7fdb7c7f9d --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/__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 .async_client import ToolsAsyncClient +from .client import ToolsClient + +__all__ = ( + "ToolsClient", + "ToolsAsyncClient", +) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/async_client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/async_client.py new file mode 100644 index 000000000000..98ed58529f14 --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/async_client.py @@ -0,0 +1,1181 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 +import logging as std_logging +import re +from typing import ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, +) + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.api_core.client_options import ClientOptions +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.cloud.dialogflow_v2beta1 import gapic_version as package_version + +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.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + +from google.cloud.dialogflow_v2beta1.services.tools import pagers +from google.cloud.dialogflow_v2beta1.types import tool +from google.cloud.dialogflow_v2beta1.types import tool as gcd_tool + +from .client import ToolsClient +from .transports.base import DEFAULT_CLIENT_INFO, ToolsTransport +from .transports.grpc_asyncio import ToolsGrpcAsyncIOTransport + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class ToolsAsyncClient: + """Tool Service for LLM powered Agent Assist. Tools can be used + to interact with remote APIs (e.g. fetching orders) to retrieve + additional information as input to LLM. + """ + + _client: ToolsClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ToolsClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ToolsClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ToolsClient._DEFAULT_ENDPOINT_TEMPLATE + _DEFAULT_UNIVERSE = ToolsClient._DEFAULT_UNIVERSE + + secret_version_path = staticmethod(ToolsClient.secret_version_path) + parse_secret_version_path = staticmethod(ToolsClient.parse_secret_version_path) + service_path = staticmethod(ToolsClient.service_path) + parse_service_path = staticmethod(ToolsClient.parse_service_path) + tool_path = staticmethod(ToolsClient.tool_path) + parse_tool_path = staticmethod(ToolsClient.parse_tool_path) + common_billing_account_path = staticmethod(ToolsClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod( + ToolsClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(ToolsClient.common_folder_path) + parse_common_folder_path = staticmethod(ToolsClient.parse_common_folder_path) + common_organization_path = staticmethod(ToolsClient.common_organization_path) + parse_common_organization_path = staticmethod( + ToolsClient.parse_common_organization_path + ) + common_project_path = staticmethod(ToolsClient.common_project_path) + parse_common_project_path = staticmethod(ToolsClient.parse_common_project_path) + common_location_path = staticmethod(ToolsClient.common_location_path) + parse_common_location_path = staticmethod(ToolsClient.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: + ToolsAsyncClient: The constructed client. + """ + return ToolsClient.from_service_account_info.__func__(ToolsAsyncClient, 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: + ToolsAsyncClient: The constructed client. + """ + return ToolsClient.from_service_account_file.__func__(ToolsAsyncClient, 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 ToolsClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ToolsTransport: + """Returns the transport used by the client instance. + + Returns: + ToolsTransport: 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 = ToolsClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[str, ToolsTransport, Callable[..., ToolsTransport]] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the tools 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,ToolsTransport,Callable[..., ToolsTransport]]]): + 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 ToolsTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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 = ToolsClient( + 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.cloud.dialogflow_v2beta1.ToolsAsyncClient`.", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.Tools", + "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.cloud.dialogflow.v2beta1.Tools", + "credentialsType": None, + }, + ) + + async def create_tool( + self, + request: Optional[Union[gcd_tool.CreateToolRequest, dict]] = None, + *, + parent: Optional[str] = None, + tool: Optional[gcd_tool.Tool] = None, + tool_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]]] = (), + ) -> gcd_tool.Tool: + r"""Creates a tool. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflow_v2beta1 + + async def sample_create_tool(): + # Create a client + client = dialogflow_v2beta1.ToolsAsyncClient() + + # Initialize request argument(s) + tool = dialogflow_v2beta1.Tool() + tool.extension_spec.name = "name_value" + tool.tool_key = "tool_key_value" + + request = dialogflow_v2beta1.CreateToolRequest( + parent="parent_value", + tool=tool, + ) + + # Make the request + response = await client.create_tool(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.dialogflow_v2beta1.types.CreateToolRequest, dict]]): + The request object. Request message of CreateTool. + parent (:class:`str`): + Required. The project/location to create tool for. + Format: + ``projects//locations/`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + tool (:class:`google.cloud.dialogflow_v2beta1.types.Tool`): + Required. The tool to create. + This corresponds to the ``tool`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + tool_id (:class:`str`): + Optional. The ID to use for the tool, which will become + the final component of the tool's resource name. + + The tool ID must be compliant with the regression + formula ``[a-zA-Z][a-zA-Z0-9_-]*`` with the characters + length in range of [3,64]. If the field is not provide, + an Id will be auto-generated. If the field is provided, + the caller is responsible for + + 1. the uniqueness of the ID, otherwise the request will + be rejected. + 2. the consistency for whether to use custom ID or not + under a project to better ensure uniqueness. + + This corresponds to the ``tool_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.cloud.dialogflow_v2beta1.types.Tool: + Represents a tool. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, tool, tool_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, gcd_tool.CreateToolRequest): + request = gcd_tool.CreateToolRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if tool is not None: + request.tool = tool + if tool_id is not None: + request.tool_id = tool_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.create_tool + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_tool( + self, + request: Optional[Union[tool.GetToolRequest, dict]] = None, + *, + 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]]] = (), + ) -> tool.Tool: + r"""Retrieves a tool. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflow_v2beta1 + + async def sample_get_tool(): + # Create a client + client = dialogflow_v2beta1.ToolsAsyncClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.GetToolRequest( + name="name_value", + ) + + # Make the request + response = await client.get_tool(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.dialogflow_v2beta1.types.GetToolRequest, dict]]): + The request object. Request message of GetTool. + name (:class:`str`): + Required. The tool resource name to retrieve. Format: + ``projects//locations//tools/`` + + This corresponds to the ``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.cloud.dialogflow_v2beta1.types.Tool: + Represents a tool. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, tool.GetToolRequest): + request = tool.GetToolRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = 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_tool] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_tools( + self, + request: Optional[Union[tool.ListToolsRequest, dict]] = None, + *, + parent: 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.ListToolsAsyncPager: + r"""Lists tools. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflow_v2beta1 + + async def sample_list_tools(): + # Create a client + client = dialogflow_v2beta1.ToolsAsyncClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.ListToolsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_tools(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.dialogflow_v2beta1.types.ListToolsRequest, dict]]): + The request object. Request message of ListTools. + parent (:class:`str`): + Required. The project/location to list tools for. + Format: + ``projects//locations/`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.dialogflow_v2beta1.services.tools.pagers.ListToolsAsyncPager: + Response of ListTools. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, tool.ListToolsRequest): + request = tool.ListToolsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.list_tools + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.ListToolsAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_tool( + self, + request: Optional[Union[tool.DeleteToolRequest, dict]] = None, + *, + 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]]] = (), + ) -> None: + r"""Deletes a tool. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflow_v2beta1 + + async def sample_delete_tool(): + # Create a client + client = dialogflow_v2beta1.ToolsAsyncClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.DeleteToolRequest( + name="name_value", + ) + + # Make the request + await client.delete_tool(request=request) + + Args: + request (Optional[Union[google.cloud.dialogflow_v2beta1.types.DeleteToolRequest, dict]]): + The request object. Request of DeleteTool. + name (:class:`str`): + Required. The tool resource name to delete. Format: + ``projects//locations//tools/`` + + This corresponds to the ``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`. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, tool.DeleteToolRequest): + request = tool.DeleteToolRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.delete_tool + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def update_tool( + self, + request: Optional[Union[gcd_tool.UpdateToolRequest, dict]] = None, + *, + tool: Optional[gcd_tool.Tool] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> gcd_tool.Tool: + r"""Updates a tool. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflow_v2beta1 + + async def sample_update_tool(): + # Create a client + client = dialogflow_v2beta1.ToolsAsyncClient() + + # Initialize request argument(s) + tool = dialogflow_v2beta1.Tool() + tool.extension_spec.name = "name_value" + tool.tool_key = "tool_key_value" + + request = dialogflow_v2beta1.UpdateToolRequest( + tool=tool, + ) + + # Make the request + response = await client.update_tool(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.dialogflow_v2beta1.types.UpdateToolRequest, dict]]): + The request object. Request of UpdateTool. + tool (:class:`google.cloud.dialogflow_v2beta1.types.Tool`): + Required. The tool to update. + The name field of tool is to identify + the tool to update. + + This corresponds to the ``tool`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Optional. The list of fields to + update. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.dialogflow_v2beta1.types.Tool: + Represents a tool. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [tool, update_mask] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, gcd_tool.UpdateToolRequest): + request = gcd_tool.UpdateToolRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if tool is not None: + request.tool = tool + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.update_tool + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("tool.name", request.tool.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 list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.list_operations] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 cancel_operation( + self, + request: Optional[operations_pb2.CancelOperationRequest] = 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 asynchronous cancellation on a long-running operation. + + The server makes a best effort to cancel the operation, but success + is not guaranteed. If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.CancelOperationRequest`): + The request object. Request message for + `CancelOperation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.CancelOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.cancel_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def get_location( + self, + request: Optional[locations_pb2.GetLocationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.Location: + r"""Gets information about a location. + + Args: + request (:class:`~.location_pb2.GetLocationRequest`): + The request object. Request message for + `GetLocation` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.location_pb2.Location: + Location object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = locations_pb2.GetLocationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.get_location] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_locations( + self, + request: Optional[locations_pb2.ListLocationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.ListLocationsResponse: + r"""Lists information about the supported locations for this service. + + Args: + request (:class:`~.location_pb2.ListLocationsRequest`): + The request object. Request message for + `ListLocations` method. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.location_pb2.ListLocationsResponse: + Response message for ``ListLocations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = locations_pb2.ListLocationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self.transport._wrapped_methods[self._client._transport.list_locations] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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) -> "ToolsAsyncClient": + 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__ = ("ToolsAsyncClient",) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/client.py new file mode 100644 index 000000000000..b6ce96fbc7bf --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/client.py @@ -0,0 +1,1660 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 ( + Callable, + Dict, + Mapping, + MutableMapping, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +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.exceptions import MutualTLSChannelError # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.cloud.dialogflow_v2beta1 import gapic_version as package_version + +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.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + +from google.cloud.dialogflow_v2beta1.services.tools import pagers +from google.cloud.dialogflow_v2beta1.types import tool +from google.cloud.dialogflow_v2beta1.types import tool as gcd_tool + +from .transports.base import DEFAULT_CLIENT_INFO, ToolsTransport +from .transports.grpc import ToolsGrpcTransport +from .transports.grpc_asyncio import ToolsGrpcAsyncIOTransport +from .transports.rest import ToolsRestTransport + + +class ToolsClientMeta(type): + """Metaclass for the Tools 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[ToolsTransport]] + _transport_registry["grpc"] = ToolsGrpcTransport + _transport_registry["grpc_asyncio"] = ToolsGrpcAsyncIOTransport + _transport_registry["rest"] = ToolsRestTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ToolsTransport]: + """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 ToolsClient(metaclass=ToolsClientMeta): + """Tool Service for LLM powered Agent Assist. Tools can be used + to interact with remote APIs (e.g. fetching orders) to retrieve + additional information as input to LLM. + """ + + @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 = "dialogflow.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "dialogflow.{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: + ToolsClient: 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: + ToolsClient: 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) -> ToolsTransport: + """Returns the transport used by the client instance. + + Returns: + ToolsTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def secret_version_path( + project: str, + secret: str, + version: str, + ) -> str: + """Returns a fully-qualified secret_version string.""" + return "projects/{project}/secrets/{secret}/versions/{version}".format( + project=project, + secret=secret, + version=version, + ) + + @staticmethod + def parse_secret_version_path(path: str) -> Dict[str, str]: + """Parses a secret_version path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/secrets/(?P.+?)/versions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def service_path( + project: str, + location: str, + namespace: str, + service: str, + ) -> str: + """Returns a fully-qualified service string.""" + return "projects/{project}/locations/{location}/namespaces/{namespace}/services/{service}".format( + project=project, + location=location, + namespace=namespace, + service=service, + ) + + @staticmethod + def parse_service_path(path: str) -> Dict[str, str]: + """Parses a service path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/namespaces/(?P.+?)/services/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def tool_path( + project: str, + location: str, + tool: str, + ) -> str: + """Returns a fully-qualified tool string.""" + return "projects/{project}/locations/{location}/tools/{tool}".format( + project=project, + location=location, + tool=tool, + ) + + @staticmethod + def parse_tool_path(path: str) -> Dict[str, str]: + """Parses a tool path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/tools/(?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 = ToolsClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ToolsClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ToolsClient._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 = ToolsClient._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, ToolsTransport, Callable[..., ToolsTransport]] + ] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the tools client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ToolsTransport,Callable[..., ToolsTransport]]]): + 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 ToolsTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + 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, + ) = ToolsClient._read_environment_variables() + self._client_cert_source = ToolsClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = ToolsClient._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, ToolsTransport) + if transport_provided: + # transport is a ToolsTransport 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(ToolsTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = self._api_endpoint or ToolsClient._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[ToolsTransport], Callable[..., ToolsTransport] + ] = ( + ToolsClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., ToolsTransport], 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.cloud.dialogflow_v2beta1.ToolsClient`.", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.Tools", + "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.cloud.dialogflow.v2beta1.Tools", + "credentialsType": None, + }, + ) + + def create_tool( + self, + request: Optional[Union[gcd_tool.CreateToolRequest, dict]] = None, + *, + parent: Optional[str] = None, + tool: Optional[gcd_tool.Tool] = None, + tool_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]]] = (), + ) -> gcd_tool.Tool: + r"""Creates a tool. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflow_v2beta1 + + def sample_create_tool(): + # Create a client + client = dialogflow_v2beta1.ToolsClient() + + # Initialize request argument(s) + tool = dialogflow_v2beta1.Tool() + tool.extension_spec.name = "name_value" + tool.tool_key = "tool_key_value" + + request = dialogflow_v2beta1.CreateToolRequest( + parent="parent_value", + tool=tool, + ) + + # Make the request + response = client.create_tool(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.dialogflow_v2beta1.types.CreateToolRequest, dict]): + The request object. Request message of CreateTool. + parent (str): + Required. The project/location to create tool for. + Format: + ``projects//locations/`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + tool (google.cloud.dialogflow_v2beta1.types.Tool): + Required. The tool to create. + This corresponds to the ``tool`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + tool_id (str): + Optional. The ID to use for the tool, which will become + the final component of the tool's resource name. + + The tool ID must be compliant with the regression + formula ``[a-zA-Z][a-zA-Z0-9_-]*`` with the characters + length in range of [3,64]. If the field is not provide, + an Id will be auto-generated. If the field is provided, + the caller is responsible for + + 1. the uniqueness of the ID, otherwise the request will + be rejected. + 2. the consistency for whether to use custom ID or not + under a project to better ensure uniqueness. + + This corresponds to the ``tool_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.cloud.dialogflow_v2beta1.types.Tool: + Represents a tool. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [parent, tool, tool_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, gcd_tool.CreateToolRequest): + request = gcd_tool.CreateToolRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if tool is not None: + request.tool = tool + if tool_id is not None: + request.tool_id = tool_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_tool] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_tool( + self, + request: Optional[Union[tool.GetToolRequest, dict]] = None, + *, + 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]]] = (), + ) -> tool.Tool: + r"""Retrieves a tool. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflow_v2beta1 + + def sample_get_tool(): + # Create a client + client = dialogflow_v2beta1.ToolsClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.GetToolRequest( + name="name_value", + ) + + # Make the request + response = client.get_tool(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.dialogflow_v2beta1.types.GetToolRequest, dict]): + The request object. Request message of GetTool. + name (str): + Required. The tool resource name to retrieve. Format: + ``projects//locations//tools/`` + + This corresponds to the ``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.cloud.dialogflow_v2beta1.types.Tool: + Represents a tool. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, tool.GetToolRequest): + request = tool.GetToolRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_tool] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.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 list_tools( + self, + request: Optional[Union[tool.ListToolsRequest, dict]] = None, + *, + parent: 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.ListToolsPager: + r"""Lists tools. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflow_v2beta1 + + def sample_list_tools(): + # Create a client + client = dialogflow_v2beta1.ToolsClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.ListToolsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_tools(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.dialogflow_v2beta1.types.ListToolsRequest, dict]): + The request object. Request message of ListTools. + parent (str): + Required. The project/location to list tools for. + Format: + ``projects//locations/`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.dialogflow_v2beta1.services.tools.pagers.ListToolsPager: + Response of ListTools. + + 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 = [parent] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, tool.ListToolsRequest): + request = tool.ListToolsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_tools] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # 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.ListToolsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_tool( + self, + request: Optional[Union[tool.DeleteToolRequest, dict]] = None, + *, + 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]]] = (), + ) -> None: + r"""Deletes a tool. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflow_v2beta1 + + def sample_delete_tool(): + # Create a client + client = dialogflow_v2beta1.ToolsClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.DeleteToolRequest( + name="name_value", + ) + + # Make the request + client.delete_tool(request=request) + + Args: + request (Union[google.cloud.dialogflow_v2beta1.types.DeleteToolRequest, dict]): + The request object. Request of DeleteTool. + name (str): + Required. The tool resource name to delete. Format: + ``projects//locations//tools/`` + + This corresponds to the ``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`. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [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, tool.DeleteToolRequest): + request = tool.DeleteToolRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_tool] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def update_tool( + self, + request: Optional[Union[gcd_tool.UpdateToolRequest, dict]] = None, + *, + tool: Optional[gcd_tool.Tool] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> gcd_tool.Tool: + r"""Updates a tool. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflow_v2beta1 + + def sample_update_tool(): + # Create a client + client = dialogflow_v2beta1.ToolsClient() + + # Initialize request argument(s) + tool = dialogflow_v2beta1.Tool() + tool.extension_spec.name = "name_value" + tool.tool_key = "tool_key_value" + + request = dialogflow_v2beta1.UpdateToolRequest( + tool=tool, + ) + + # Make the request + response = client.update_tool(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.dialogflow_v2beta1.types.UpdateToolRequest, dict]): + The request object. Request of UpdateTool. + tool (google.cloud.dialogflow_v2beta1.types.Tool): + Required. The tool to update. + The name field of tool is to identify + the tool to update. + + This corresponds to the ``tool`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. The list of fields to + update. + + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + google.cloud.dialogflow_v2beta1.types.Tool: + Represents a tool. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [tool, update_mask] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, gcd_tool.UpdateToolRequest): + request = gcd_tool.UpdateToolRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if tool is not None: + request.tool = tool + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_tool] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("tool.name", request.tool.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) -> "ToolsClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_operations] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.operations_pb2.Operation: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + def cancel_operation( + self, + request: Optional[operations_pb2.CancelOperationRequest] = 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 asynchronous cancellation on a long-running operation. + + The server makes a best effort to cancel the operation, but success + is not guaranteed. If the server doesn't support this method, it returns + `google.rpc.Code.UNIMPLEMENTED`. + + Args: + request (:class:`~.operations_pb2.CancelOperationRequest`): + The request object. Request message for + `CancelOperation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + None + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.CancelOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.cancel_operation] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def get_location( + self, + request: Optional[locations_pb2.GetLocationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.Location: + r"""Gets information about a location. + + Args: + request (:class:`~.location_pb2.GetLocationRequest`): + The request object. Request message for + `GetLocation` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.location_pb2.Location: + Location object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = locations_pb2.GetLocationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_location] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + def list_locations( + self, + request: Optional[locations_pb2.ListLocationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.ListLocationsResponse: + r"""Lists information about the supported locations for this service. + + Args: + request (:class:`~.location_pb2.ListLocationsRequest`): + The request object. Request message for + `ListLocations` method. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + Returns: + ~.location_pb2.ListLocationsResponse: + Response message for ``ListLocations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = locations_pb2.ListLocationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_locations] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("ToolsClient",) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/pagers.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/pagers.py new file mode 100644 index 000000000000..30a5c21c1498 --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/pagers.py @@ -0,0 +1,197 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Iterator, + Optional, + Sequence, + Tuple, + Union, +) + +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 + +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.cloud.dialogflow_v2beta1.types import tool + + +class ListToolsPager: + """A pager for iterating through ``list_tools`` requests. + + This class thinly wraps an initial + :class:`google.cloud.dialogflow_v2beta1.types.ListToolsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``tools`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListTools`` requests and continue to iterate + through the ``tools`` field on the + corresponding responses. + + All the usual :class:`google.cloud.dialogflow_v2beta1.types.ListToolsResponse` + 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[..., tool.ListToolsResponse], + request: tool.ListToolsRequest, + response: tool.ListToolsResponse, + *, + 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.cloud.dialogflow_v2beta1.types.ListToolsRequest): + The initial request object. + response (google.cloud.dialogflow_v2beta1.types.ListToolsResponse): + 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 = tool.ListToolsRequest(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[tool.ListToolsResponse]: + 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[tool.Tool]: + for page in self.pages: + yield from page.tools + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListToolsAsyncPager: + """A pager for iterating through ``list_tools`` requests. + + This class thinly wraps an initial + :class:`google.cloud.dialogflow_v2beta1.types.ListToolsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``tools`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListTools`` requests and continue to iterate + through the ``tools`` field on the + corresponding responses. + + All the usual :class:`google.cloud.dialogflow_v2beta1.types.ListToolsResponse` + 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[tool.ListToolsResponse]], + request: tool.ListToolsRequest, + response: tool.ListToolsResponse, + *, + 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.cloud.dialogflow_v2beta1.types.ListToolsRequest): + The initial request object. + response (google.cloud.dialogflow_v2beta1.types.ListToolsResponse): + 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 = tool.ListToolsRequest(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[tool.ListToolsResponse]: + 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[tool.Tool]: + async def async_generator(): + async for page in self.pages: + for response in page.tools: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/transports/README.rst b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/transports/README.rst new file mode 100644 index 000000000000..f7b77e1167bf --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`ToolsTransport` is the ABC for all transports. +- public child `ToolsGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `ToolsGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseToolsRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `ToolsRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/transports/__init__.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/transports/__init__.py new file mode 100644 index 000000000000..6cd24e40959c --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/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 typing import Dict, Type + +from .base import ToolsTransport +from .grpc import ToolsGrpcTransport +from .grpc_asyncio import ToolsGrpcAsyncIOTransport +from .rest import ToolsRestInterceptor, ToolsRestTransport + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ToolsTransport]] +_transport_registry["grpc"] = ToolsGrpcTransport +_transport_registry["grpc_asyncio"] = ToolsGrpcAsyncIOTransport +_transport_registry["rest"] = ToolsRestTransport + +__all__ = ( + "ToolsTransport", + "ToolsGrpcTransport", + "ToolsGrpcAsyncIOTransport", + "ToolsRestTransport", + "ToolsRestInterceptor", +) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/transports/base.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/transports/base.py new file mode 100644 index 000000000000..e91562584f68 --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/transports/base.py @@ -0,0 +1,296 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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, Dict, Optional, Sequence, Union + +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +import google.auth # type: ignore +from google.auth import credentials as ga_credentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf +from google.protobuf import empty_pb2 # type: ignore + +from google.cloud.dialogflow_v2beta1 import gapic_version as package_version +from google.cloud.dialogflow_v2beta1.types import tool +from google.cloud.dialogflow_v2beta1.types import tool as gcd_tool + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_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 ToolsTransport(abc.ABC): + """Abstract transport class for Tools.""" + + AUTH_SCOPES = ( + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/dialogflow", + ) + + DEFAULT_HOST: str = "dialogflow.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: 'dialogflow.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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_tool: gapic_v1.method.wrap_method( + self.create_tool, + default_timeout=None, + client_info=client_info, + ), + self.get_tool: gapic_v1.method.wrap_method( + self.get_tool, + default_timeout=None, + client_info=client_info, + ), + self.list_tools: gapic_v1.method.wrap_method( + self.list_tools, + default_timeout=None, + client_info=client_info, + ), + self.delete_tool: gapic_v1.method.wrap_method( + self.delete_tool, + default_timeout=None, + client_info=client_info, + ), + self.update_tool: gapic_v1.method.wrap_method( + self.update_tool, + default_timeout=None, + client_info=client_info, + ), + self.get_location: gapic_v1.method.wrap_method( + self.get_location, + default_timeout=None, + client_info=client_info, + ), + self.list_locations: gapic_v1.method.wrap_method( + self.list_locations, + default_timeout=None, + client_info=client_info, + ), + self.cancel_operation: gapic_v1.method.wrap_method( + self.cancel_operation, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: gapic_v1.method.wrap_method( + self.get_operation, + default_timeout=None, + client_info=client_info, + ), + self.list_operations: gapic_v1.method.wrap_method( + self.list_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 create_tool( + self, + ) -> Callable[ + [gcd_tool.CreateToolRequest], Union[gcd_tool.Tool, Awaitable[gcd_tool.Tool]] + ]: + raise NotImplementedError() + + @property + def get_tool( + self, + ) -> Callable[[tool.GetToolRequest], Union[tool.Tool, Awaitable[tool.Tool]]]: + raise NotImplementedError() + + @property + def list_tools( + self, + ) -> Callable[ + [tool.ListToolsRequest], + Union[tool.ListToolsResponse, Awaitable[tool.ListToolsResponse]], + ]: + raise NotImplementedError() + + @property + def delete_tool( + self, + ) -> Callable[ + [tool.DeleteToolRequest], Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]] + ]: + raise NotImplementedError() + + @property + def update_tool( + self, + ) -> Callable[ + [gcd_tool.UpdateToolRequest], Union[gcd_tool.Tool, Awaitable[gcd_tool.Tool]] + ]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[ + operations_pb2.ListOperationsResponse, + Awaitable[operations_pb2.ListOperationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def cancel_operation( + self, + ) -> Callable[[operations_pb2.CancelOperationRequest], None,]: + raise NotImplementedError() + + @property + def get_location( + self, + ) -> Callable[ + [locations_pb2.GetLocationRequest], + Union[locations_pb2.Location, Awaitable[locations_pb2.Location]], + ]: + raise NotImplementedError() + + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], + Union[ + locations_pb2.ListLocationsResponse, + Awaitable[locations_pb2.ListLocationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ToolsTransport",) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/transports/grpc.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/transports/grpc.py new file mode 100644 index 000000000000..9585c84b9b7c --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/transports/grpc.py @@ -0,0 +1,547 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import json +import logging as std_logging +import pickle +from typing import Callable, Dict, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import gapic_v1, grpc_helpers +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.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message +import grpc # type: ignore +import proto # type: ignore + +from google.cloud.dialogflow_v2beta1.types import tool +from google.cloud.dialogflow_v2beta1.types import tool as gcd_tool + +from .base import DEFAULT_CLIENT_INFO, ToolsTransport + +try: + from google.api_core import client_logging # 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.cloud.dialogflow.v2beta1.Tools", + "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.cloud.dialogflow.v2beta1.Tools", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ToolsGrpcTransport(ToolsTransport): + """gRPC backend transport for Tools. + + Tool Service for LLM powered Agent Assist. Tools can be used + to interact with remote APIs (e.g. fetching orders) to retrieve + additional information as input to LLM. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call 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 = "dialogflow.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: 'dialogflow.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the 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 = "dialogflow.googleapis.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_tool(self) -> Callable[[gcd_tool.CreateToolRequest], gcd_tool.Tool]: + r"""Return a callable for the create tool method over gRPC. + + Creates a tool. + + Returns: + Callable[[~.CreateToolRequest], + ~.Tool]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tool" not in self._stubs: + self._stubs["create_tool"] = self._logged_channel.unary_unary( + "/google.cloud.dialogflow.v2beta1.Tools/CreateTool", + request_serializer=gcd_tool.CreateToolRequest.serialize, + response_deserializer=gcd_tool.Tool.deserialize, + ) + return self._stubs["create_tool"] + + @property + def get_tool(self) -> Callable[[tool.GetToolRequest], tool.Tool]: + r"""Return a callable for the get tool method over gRPC. + + Retrieves a tool. + + Returns: + Callable[[~.GetToolRequest], + ~.Tool]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tool" not in self._stubs: + self._stubs["get_tool"] = self._logged_channel.unary_unary( + "/google.cloud.dialogflow.v2beta1.Tools/GetTool", + request_serializer=tool.GetToolRequest.serialize, + response_deserializer=tool.Tool.deserialize, + ) + return self._stubs["get_tool"] + + @property + def list_tools(self) -> Callable[[tool.ListToolsRequest], tool.ListToolsResponse]: + r"""Return a callable for the list tools method over gRPC. + + Lists tools. + + Returns: + Callable[[~.ListToolsRequest], + ~.ListToolsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tools" not in self._stubs: + self._stubs["list_tools"] = self._logged_channel.unary_unary( + "/google.cloud.dialogflow.v2beta1.Tools/ListTools", + request_serializer=tool.ListToolsRequest.serialize, + response_deserializer=tool.ListToolsResponse.deserialize, + ) + return self._stubs["list_tools"] + + @property + def delete_tool(self) -> Callable[[tool.DeleteToolRequest], empty_pb2.Empty]: + r"""Return a callable for the delete tool method over gRPC. + + Deletes a tool. + + Returns: + Callable[[~.DeleteToolRequest], + ~.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 "delete_tool" not in self._stubs: + self._stubs["delete_tool"] = self._logged_channel.unary_unary( + "/google.cloud.dialogflow.v2beta1.Tools/DeleteTool", + request_serializer=tool.DeleteToolRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["delete_tool"] + + @property + def update_tool(self) -> Callable[[gcd_tool.UpdateToolRequest], gcd_tool.Tool]: + r"""Return a callable for the update tool method over gRPC. + + Updates a tool. + + Returns: + Callable[[~.UpdateToolRequest], + ~.Tool]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tool" not in self._stubs: + self._stubs["update_tool"] = self._logged_channel.unary_unary( + "/google.cloud.dialogflow.v2beta1.Tools/UpdateTool", + request_serializer=gcd_tool.UpdateToolRequest.serialize, + response_deserializer=gcd_tool.Tool.deserialize, + ) + return self._stubs["update_tool"] + + def close(self): + self._logged_channel.close() + + @property + def cancel_operation( + self, + ) -> Callable[[operations_pb2.CancelOperationRequest], None]: + r"""Return a callable for the cancel_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "cancel_operation" not in self._stubs: + self._stubs["cancel_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/CancelOperation", + request_serializer=operations_pb2.CancelOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["cancel_operation"] + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-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_operation" not in self._stubs: + self._stubs["get_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-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_operations" not in self._stubs: + self._stubs["list_operations"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], locations_pb2.ListLocationsResponse + ]: + r"""Return a callable for the list locations method over gRPC.""" + # Generate a "stub function" on-the-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_locations" not in self._stubs: + self._stubs["list_locations"] = self._logged_channel.unary_unary( + "/google.cloud.location.Locations/ListLocations", + request_serializer=locations_pb2.ListLocationsRequest.SerializeToString, + response_deserializer=locations_pb2.ListLocationsResponse.FromString, + ) + return self._stubs["list_locations"] + + @property + def get_location( + self, + ) -> Callable[[locations_pb2.GetLocationRequest], locations_pb2.Location]: + r"""Return a callable for the list locations method over gRPC.""" + # Generate a "stub function" on-the-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_location" not in self._stubs: + self._stubs["get_location"] = self._logged_channel.unary_unary( + "/google.cloud.location.Locations/GetLocation", + request_serializer=locations_pb2.GetLocationRequest.SerializeToString, + response_deserializer=locations_pb2.Location.FromString, + ) + return self._stubs["get_location"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("ToolsGrpcTransport",) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/transports/grpc_asyncio.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/transports/grpc_asyncio.py new file mode 100644 index 000000000000..f1ef56d7cdd2 --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/transports/grpc_asyncio.py @@ -0,0 +1,623 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 json +import logging as std_logging +import pickle +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, grpc_helpers_async +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message +import grpc # type: ignore +from grpc.experimental import aio # type: ignore +import proto # type: ignore + +from google.cloud.dialogflow_v2beta1.types import tool +from google.cloud.dialogflow_v2beta1.types import tool as gcd_tool + +from .base import DEFAULT_CLIENT_INFO, ToolsTransport +from .grpc import ToolsGrpcTransport + +try: + from google.api_core import client_logging # 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.cloud.dialogflow.v2beta1.Tools", + "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.cloud.dialogflow.v2beta1.Tools", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ToolsGrpcAsyncIOTransport(ToolsTransport): + """gRPC AsyncIO backend transport for Tools. + + Tool Service for LLM powered Agent Assist. Tools can be used + to interact with remote APIs (e.g. fetching orders) to retrieve + additional information as input to LLM. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call 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 = "dialogflow.googleapis.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 = "dialogflow.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: 'dialogflow.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the 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_tool( + self, + ) -> Callable[[gcd_tool.CreateToolRequest], Awaitable[gcd_tool.Tool]]: + r"""Return a callable for the create tool method over gRPC. + + Creates a tool. + + Returns: + Callable[[~.CreateToolRequest], + Awaitable[~.Tool]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tool" not in self._stubs: + self._stubs["create_tool"] = self._logged_channel.unary_unary( + "/google.cloud.dialogflow.v2beta1.Tools/CreateTool", + request_serializer=gcd_tool.CreateToolRequest.serialize, + response_deserializer=gcd_tool.Tool.deserialize, + ) + return self._stubs["create_tool"] + + @property + def get_tool(self) -> Callable[[tool.GetToolRequest], Awaitable[tool.Tool]]: + r"""Return a callable for the get tool method over gRPC. + + Retrieves a tool. + + Returns: + Callable[[~.GetToolRequest], + Awaitable[~.Tool]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tool" not in self._stubs: + self._stubs["get_tool"] = self._logged_channel.unary_unary( + "/google.cloud.dialogflow.v2beta1.Tools/GetTool", + request_serializer=tool.GetToolRequest.serialize, + response_deserializer=tool.Tool.deserialize, + ) + return self._stubs["get_tool"] + + @property + def list_tools( + self, + ) -> Callable[[tool.ListToolsRequest], Awaitable[tool.ListToolsResponse]]: + r"""Return a callable for the list tools method over gRPC. + + Lists tools. + + Returns: + Callable[[~.ListToolsRequest], + Awaitable[~.ListToolsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tools" not in self._stubs: + self._stubs["list_tools"] = self._logged_channel.unary_unary( + "/google.cloud.dialogflow.v2beta1.Tools/ListTools", + request_serializer=tool.ListToolsRequest.serialize, + response_deserializer=tool.ListToolsResponse.deserialize, + ) + return self._stubs["list_tools"] + + @property + def delete_tool( + self, + ) -> Callable[[tool.DeleteToolRequest], Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete tool method over gRPC. + + Deletes a tool. + + Returns: + Callable[[~.DeleteToolRequest], + 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 "delete_tool" not in self._stubs: + self._stubs["delete_tool"] = self._logged_channel.unary_unary( + "/google.cloud.dialogflow.v2beta1.Tools/DeleteTool", + request_serializer=tool.DeleteToolRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["delete_tool"] + + @property + def update_tool( + self, + ) -> Callable[[gcd_tool.UpdateToolRequest], Awaitable[gcd_tool.Tool]]: + r"""Return a callable for the update tool method over gRPC. + + Updates a tool. + + Returns: + Callable[[~.UpdateToolRequest], + Awaitable[~.Tool]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-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_tool" not in self._stubs: + self._stubs["update_tool"] = self._logged_channel.unary_unary( + "/google.cloud.dialogflow.v2beta1.Tools/UpdateTool", + request_serializer=gcd_tool.UpdateToolRequest.serialize, + response_deserializer=gcd_tool.Tool.deserialize, + ) + return self._stubs["update_tool"] + + 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_tool: self._wrap_method( + self.create_tool, + default_timeout=None, + client_info=client_info, + ), + self.get_tool: self._wrap_method( + self.get_tool, + default_timeout=None, + client_info=client_info, + ), + self.list_tools: self._wrap_method( + self.list_tools, + default_timeout=None, + client_info=client_info, + ), + self.delete_tool: self._wrap_method( + self.delete_tool, + default_timeout=None, + client_info=client_info, + ), + self.update_tool: self._wrap_method( + self.update_tool, + default_timeout=None, + client_info=client_info, + ), + self.get_location: self._wrap_method( + self.get_location, + default_timeout=None, + client_info=client_info, + ), + self.list_locations: self._wrap_method( + self.list_locations, + default_timeout=None, + client_info=client_info, + ), + self.cancel_operation: self._wrap_method( + self.cancel_operation, + default_timeout=None, + client_info=client_info, + ), + self.get_operation: self._wrap_method( + self.get_operation, + default_timeout=None, + client_info=client_info, + ), + self.list_operations: self._wrap_method( + self.list_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" + + @property + def cancel_operation( + self, + ) -> Callable[[operations_pb2.CancelOperationRequest], None]: + r"""Return a callable for the cancel_operation method over gRPC.""" + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "cancel_operation" not in self._stubs: + self._stubs["cancel_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/CancelOperation", + request_serializer=operations_pb2.CancelOperationRequest.SerializeToString, + response_deserializer=None, + ) + return self._stubs["cancel_operation"] + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC.""" + # Generate a "stub function" on-the-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_operation" not in self._stubs: + self._stubs["get_operation"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse + ]: + r"""Return a callable for the list_operations method over gRPC.""" + # Generate a "stub function" on-the-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_operations" not in self._stubs: + self._stubs["list_operations"] = self._logged_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def list_locations( + self, + ) -> Callable[ + [locations_pb2.ListLocationsRequest], locations_pb2.ListLocationsResponse + ]: + r"""Return a callable for the list locations method over gRPC.""" + # Generate a "stub function" on-the-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_locations" not in self._stubs: + self._stubs["list_locations"] = self._logged_channel.unary_unary( + "/google.cloud.location.Locations/ListLocations", + request_serializer=locations_pb2.ListLocationsRequest.SerializeToString, + response_deserializer=locations_pb2.ListLocationsResponse.FromString, + ) + return self._stubs["list_locations"] + + @property + def get_location( + self, + ) -> Callable[[locations_pb2.GetLocationRequest], locations_pb2.Location]: + r"""Return a callable for the list locations method over gRPC.""" + # Generate a "stub function" on-the-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_location" not in self._stubs: + self._stubs["get_location"] = self._logged_channel.unary_unary( + "/google.cloud.location.Locations/GetLocation", + request_serializer=locations_pb2.GetLocationRequest.SerializeToString, + response_deserializer=locations_pb2.Location.FromString, + ) + return self._stubs["get_location"] + + +__all__ = ("ToolsGrpcAsyncIOTransport",) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/transports/rest.py new file mode 100644 index 000000000000..4e798ec9d711 --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/transports/rest.py @@ -0,0 +1,1928 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import dataclasses +import json # type: ignore +import logging +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +import warnings + +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1, rest_helpers, rest_streaming +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.requests import AuthorizedSession # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +import google.protobuf +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import json_format +from requests import __version__ as requests_version + +from google.cloud.dialogflow_v2beta1.types import tool +from google.cloud.dialogflow_v2beta1.types import tool as gcd_tool + +from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO +from .rest_base import _BaseToolsRestTransport + +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 = logging.getLogger(__name__) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version, + grpc_version=None, + rest_version=f"requests@{requests_version}", +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class ToolsRestInterceptor: + """Interceptor for Tools. + + Interceptors are used to manipulate requests, request metadata, and responses + in arbitrary ways. + Example use cases include: + * Logging + * Verifying requests according to service or custom semantics + * Stripping extraneous information from responses + + These use cases and more can be enabled by injecting an + instance of a custom subclass when constructing the ToolsRestTransport. + + .. code-block:: python + class MyCustomToolsInterceptor(ToolsRestInterceptor): + def pre_create_tool(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_tool(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_tool(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_get_tool(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_tool(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_tools(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_tools(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_tool(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_tool(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ToolsRestTransport(interceptor=MyCustomToolsInterceptor()) + client = ToolsClient(transport=transport) + + + """ + + def pre_create_tool( + self, + request: gcd_tool.CreateToolRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_tool.CreateToolRequest, Sequence[Tuple[str, Union[str, bytes]]]]: + """Pre-rpc interceptor for create_tool + + Override in a subclass to manipulate the request or metadata + before they are sent to the Tools server. + """ + return request, metadata + + def post_create_tool(self, response: gcd_tool.Tool) -> gcd_tool.Tool: + """Post-rpc interceptor for create_tool + + DEPRECATED. Please use the `post_create_tool_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the Tools server but before + it is returned to user code. This `post_create_tool` interceptor runs + before the `post_create_tool_with_metadata` interceptor. + """ + return response + + def post_create_tool_with_metadata( + self, response: gcd_tool.Tool, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[gcd_tool.Tool, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_tool + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Tools server but before it is returned to user code. + + We recommend only using this `post_create_tool_with_metadata` + interceptor in new development instead of the `post_create_tool` interceptor. + When both interceptors are used, this `post_create_tool_with_metadata` interceptor runs after the + `post_create_tool` interceptor. The (possibly modified) response returned by + `post_create_tool` will be passed to + `post_create_tool_with_metadata`. + """ + return response, metadata + + def pre_delete_tool( + self, + request: tool.DeleteToolRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[tool.DeleteToolRequest, Sequence[Tuple[str, Union[str, bytes]]]]: + """Pre-rpc interceptor for delete_tool + + Override in a subclass to manipulate the request or metadata + before they are sent to the Tools server. + """ + return request, metadata + + def pre_get_tool( + self, + request: tool.GetToolRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[tool.GetToolRequest, Sequence[Tuple[str, Union[str, bytes]]]]: + """Pre-rpc interceptor for get_tool + + Override in a subclass to manipulate the request or metadata + before they are sent to the Tools server. + """ + return request, metadata + + def post_get_tool(self, response: tool.Tool) -> tool.Tool: + """Post-rpc interceptor for get_tool + + DEPRECATED. Please use the `post_get_tool_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the Tools server but before + it is returned to user code. This `post_get_tool` interceptor runs + before the `post_get_tool_with_metadata` interceptor. + """ + return response + + def post_get_tool_with_metadata( + self, response: tool.Tool, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[tool.Tool, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_tool + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Tools server but before it is returned to user code. + + We recommend only using this `post_get_tool_with_metadata` + interceptor in new development instead of the `post_get_tool` interceptor. + When both interceptors are used, this `post_get_tool_with_metadata` interceptor runs after the + `post_get_tool` interceptor. The (possibly modified) response returned by + `post_get_tool` will be passed to + `post_get_tool_with_metadata`. + """ + return response, metadata + + def pre_list_tools( + self, + request: tool.ListToolsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[tool.ListToolsRequest, Sequence[Tuple[str, Union[str, bytes]]]]: + """Pre-rpc interceptor for list_tools + + Override in a subclass to manipulate the request or metadata + before they are sent to the Tools server. + """ + return request, metadata + + def post_list_tools( + self, response: tool.ListToolsResponse + ) -> tool.ListToolsResponse: + """Post-rpc interceptor for list_tools + + DEPRECATED. Please use the `post_list_tools_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the Tools server but before + it is returned to user code. This `post_list_tools` interceptor runs + before the `post_list_tools_with_metadata` interceptor. + """ + return response + + def post_list_tools_with_metadata( + self, + response: tool.ListToolsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[tool.ListToolsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_tools + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Tools server but before it is returned to user code. + + We recommend only using this `post_list_tools_with_metadata` + interceptor in new development instead of the `post_list_tools` interceptor. + When both interceptors are used, this `post_list_tools_with_metadata` interceptor runs after the + `post_list_tools` interceptor. The (possibly modified) response returned by + `post_list_tools` will be passed to + `post_list_tools_with_metadata`. + """ + return response, metadata + + def pre_update_tool( + self, + request: gcd_tool.UpdateToolRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_tool.UpdateToolRequest, Sequence[Tuple[str, Union[str, bytes]]]]: + """Pre-rpc interceptor for update_tool + + Override in a subclass to manipulate the request or metadata + before they are sent to the Tools server. + """ + return request, metadata + + def post_update_tool(self, response: gcd_tool.Tool) -> gcd_tool.Tool: + """Post-rpc interceptor for update_tool + + DEPRECATED. Please use the `post_update_tool_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the Tools server but before + it is returned to user code. This `post_update_tool` interceptor runs + before the `post_update_tool_with_metadata` interceptor. + """ + return response + + def post_update_tool_with_metadata( + self, response: gcd_tool.Tool, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[gcd_tool.Tool, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_tool + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Tools server but before it is returned to user code. + + We recommend only using this `post_update_tool_with_metadata` + interceptor in new development instead of the `post_update_tool` interceptor. + When both interceptors are used, this `post_update_tool_with_metadata` interceptor runs after the + `post_update_tool` interceptor. The (possibly modified) response returned by + `post_update_tool` will be passed to + `post_update_tool_with_metadata`. + """ + return response, metadata + + def pre_get_location( + self, + request: locations_pb2.GetLocationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + locations_pb2.GetLocationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_location + + Override in a subclass to manipulate the request or metadata + before they are sent to the Tools server. + """ + return request, metadata + + def post_get_location( + self, response: locations_pb2.Location + ) -> locations_pb2.Location: + """Post-rpc interceptor for get_location + + Override in a subclass to manipulate the response + after it is returned by the Tools server but before + it is returned to user code. + """ + return response + + def pre_list_locations( + self, + request: locations_pb2.ListLocationsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + locations_pb2.ListLocationsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for list_locations + + Override in a subclass to manipulate the request or metadata + before they are sent to the Tools server. + """ + return request, metadata + + def post_list_locations( + self, response: locations_pb2.ListLocationsResponse + ) -> locations_pb2.ListLocationsResponse: + """Post-rpc interceptor for list_locations + + Override in a subclass to manipulate the response + after it is returned by the Tools server but before + it is returned to user code. + """ + return response + + def pre_cancel_operation( + self, + request: operations_pb2.CancelOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.CancelOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for cancel_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the Tools server. + """ + return request, metadata + + def post_cancel_operation(self, response: None) -> None: + """Post-rpc interceptor for cancel_operation + + Override in a subclass to manipulate the response + after it is returned by the Tools server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, + request: operations_pb2.GetOperationRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.GetOperationRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the Tools server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the Tools server but before + it is returned to user code. + """ + return response + + def pre_list_operations( + self, + request: operations_pb2.ListOperationsRequest, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + operations_pb2.ListOperationsRequest, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the Tools server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the Tools server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ToolsRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ToolsRestInterceptor + + +class ToolsRestTransport(_BaseToolsRestTransport): + """REST backend synchronous transport for Tools. + + Tool Service for LLM powered Agent Assist. Tools can be used + to interact with remote APIs (e.g. fetching orders) to retrieve + additional information as input to LLM. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "dialogflow.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + interceptor: Optional[ToolsRestInterceptor] = None, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'dialogflow.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to 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 ignored if ``channel`` 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 ``channel`` is provided. + client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client + certificate to configure mutual TLS HTTP channel. It is ignored + if ``channel`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. + # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the + # credentials object + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + url_scheme=url_scheme, + api_audience=api_audience, + ) + self._session = AuthorizedSession( + self._credentials, default_host=self.DEFAULT_HOST + ) + if client_cert_source_for_mtls: + self._session.configure_mtls_channel(client_cert_source_for_mtls) + self._interceptor = interceptor or ToolsRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _CreateTool(_BaseToolsRestTransport._BaseCreateTool, ToolsRestStub): + def __hash__(self): + return hash("ToolsRestTransport.CreateTool") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: gcd_tool.CreateToolRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> gcd_tool.Tool: + r"""Call the create tool method over HTTP. + + Args: + request (~.gcd_tool.CreateToolRequest): + The request object. Request message of CreateTool. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.gcd_tool.Tool: + Represents a tool. + """ + + http_options = _BaseToolsRestTransport._BaseCreateTool._get_http_options() + + request, metadata = self._interceptor.pre_create_tool(request, metadata) + transcoded_request = ( + _BaseToolsRestTransport._BaseCreateTool._get_transcoded_request( + http_options, request + ) + ) + + body = _BaseToolsRestTransport._BaseCreateTool._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = ( + _BaseToolsRestTransport._BaseCreateTool._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.dialogflow_v2beta1.ToolsClient.CreateTool", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.Tools", + "rpcName": "CreateTool", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ToolsRestTransport._CreateTool._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = gcd_tool.Tool() + pb_resp = gcd_tool.Tool.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_create_tool(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_tool_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = gcd_tool.Tool.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.dialogflow_v2beta1.ToolsClient.create_tool", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.Tools", + "rpcName": "CreateTool", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _DeleteTool(_BaseToolsRestTransport._BaseDeleteTool, ToolsRestStub): + def __hash__(self): + return hash("ToolsRestTransport.DeleteTool") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: tool.DeleteToolRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + r"""Call the delete tool method over HTTP. + + Args: + request (~.tool.DeleteToolRequest): + The request object. Request of DeleteTool. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + + http_options = _BaseToolsRestTransport._BaseDeleteTool._get_http_options() + + request, metadata = self._interceptor.pre_delete_tool(request, metadata) + transcoded_request = ( + _BaseToolsRestTransport._BaseDeleteTool._get_transcoded_request( + http_options, request + ) + ) + + # Jsonify the query params + query_params = ( + _BaseToolsRestTransport._BaseDeleteTool._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.dialogflow_v2beta1.ToolsClient.DeleteTool", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.Tools", + "rpcName": "DeleteTool", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ToolsRestTransport._DeleteTool._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _GetTool(_BaseToolsRestTransport._BaseGetTool, ToolsRestStub): + def __hash__(self): + return hash("ToolsRestTransport.GetTool") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: tool.GetToolRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> tool.Tool: + r"""Call the get tool method over HTTP. + + Args: + request (~.tool.GetToolRequest): + The request object. Request message of GetTool. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.tool.Tool: + Represents a tool. + """ + + http_options = _BaseToolsRestTransport._BaseGetTool._get_http_options() + + request, metadata = self._interceptor.pre_get_tool(request, metadata) + transcoded_request = ( + _BaseToolsRestTransport._BaseGetTool._get_transcoded_request( + http_options, request + ) + ) + + # Jsonify the query params + query_params = _BaseToolsRestTransport._BaseGetTool._get_query_params_json( + transcoded_request + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.dialogflow_v2beta1.ToolsClient.GetTool", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.Tools", + "rpcName": "GetTool", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ToolsRestTransport._GetTool._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = tool.Tool() + pb_resp = tool.Tool.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_get_tool(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_tool_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = tool.Tool.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.dialogflow_v2beta1.ToolsClient.get_tool", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.Tools", + "rpcName": "GetTool", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _ListTools(_BaseToolsRestTransport._BaseListTools, ToolsRestStub): + def __hash__(self): + return hash("ToolsRestTransport.ListTools") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: tool.ListToolsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> tool.ListToolsResponse: + r"""Call the list tools method over HTTP. + + Args: + request (~.tool.ListToolsRequest): + The request object. Request message of ListTools. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.tool.ListToolsResponse: + Response of ListTools. + """ + + http_options = _BaseToolsRestTransport._BaseListTools._get_http_options() + + request, metadata = self._interceptor.pre_list_tools(request, metadata) + transcoded_request = ( + _BaseToolsRestTransport._BaseListTools._get_transcoded_request( + http_options, request + ) + ) + + # Jsonify the query params + query_params = ( + _BaseToolsRestTransport._BaseListTools._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.dialogflow_v2beta1.ToolsClient.ListTools", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.Tools", + "rpcName": "ListTools", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ToolsRestTransport._ListTools._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = tool.ListToolsResponse() + pb_resp = tool.ListToolsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_list_tools(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_tools_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = tool.ListToolsResponse.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.dialogflow_v2beta1.ToolsClient.list_tools", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.Tools", + "rpcName": "ListTools", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + class _UpdateTool(_BaseToolsRestTransport._BaseUpdateTool, ToolsRestStub): + def __hash__(self): + return hash("ToolsRestTransport.UpdateTool") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + return response + + def __call__( + self, + request: gcd_tool.UpdateToolRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> gcd_tool.Tool: + r"""Call the update tool method over HTTP. + + Args: + request (~.gcd_tool.UpdateToolRequest): + The request object. Request of UpdateTool. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + ~.gcd_tool.Tool: + Represents a tool. + """ + + http_options = _BaseToolsRestTransport._BaseUpdateTool._get_http_options() + + request, metadata = self._interceptor.pre_update_tool(request, metadata) + transcoded_request = ( + _BaseToolsRestTransport._BaseUpdateTool._get_transcoded_request( + http_options, request + ) + ) + + body = _BaseToolsRestTransport._BaseUpdateTool._get_request_body_json( + transcoded_request + ) + + # Jsonify the query params + query_params = ( + _BaseToolsRestTransport._BaseUpdateTool._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = type(request).to_json(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.dialogflow_v2beta1.ToolsClient.UpdateTool", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.Tools", + "rpcName": "UpdateTool", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ToolsRestTransport._UpdateTool._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = gcd_tool.Tool() + pb_resp = gcd_tool.Tool.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + + resp = self._interceptor.post_update_tool(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_tool_with_metadata( + resp, response_metadata + ) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = gcd_tool.Tool.to_json(response) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.dialogflow_v2beta1.ToolsClient.update_tool", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.Tools", + "rpcName": "UpdateTool", + "metadata": http_response["headers"], + "httpResponse": http_response, + }, + ) + return resp + + @property + def create_tool(self) -> Callable[[gcd_tool.CreateToolRequest], gcd_tool.Tool]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateTool(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_tool(self) -> Callable[[tool.DeleteToolRequest], empty_pb2.Empty]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteTool(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_tool(self) -> Callable[[tool.GetToolRequest], tool.Tool]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetTool(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_tools(self) -> Callable[[tool.ListToolsRequest], tool.ListToolsResponse]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListTools(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_tool(self) -> Callable[[gcd_tool.UpdateToolRequest], gcd_tool.Tool]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateTool(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_location(self): + return self._GetLocation(self._session, self._host, self._interceptor) # type: ignore + + class _GetLocation(_BaseToolsRestTransport._BaseGetLocation, ToolsRestStub): + def __hash__(self): + return hash("ToolsRestTransport.GetLocation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: locations_pb2.GetLocationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.Location: + r"""Call the get location method over HTTP. + + Args: + request (locations_pb2.GetLocationRequest): + The request object for GetLocation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + locations_pb2.Location: Response from GetLocation method. + """ + + http_options = _BaseToolsRestTransport._BaseGetLocation._get_http_options() + + request, metadata = self._interceptor.pre_get_location(request, metadata) + transcoded_request = ( + _BaseToolsRestTransport._BaseGetLocation._get_transcoded_request( + http_options, request + ) + ) + + # Jsonify the query params + query_params = ( + _BaseToolsRestTransport._BaseGetLocation._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.dialogflow_v2beta1.ToolsClient.GetLocation", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.Tools", + "rpcName": "GetLocation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ToolsRestTransport._GetLocation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = locations_pb2.Location() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_location(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.dialogflow_v2beta1.ToolsAsyncClient.GetLocation", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.Tools", + "rpcName": "GetLocation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def list_locations(self): + return self._ListLocations(self._session, self._host, self._interceptor) # type: ignore + + class _ListLocations(_BaseToolsRestTransport._BaseListLocations, ToolsRestStub): + def __hash__(self): + return hash("ToolsRestTransport.ListLocations") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: locations_pb2.ListLocationsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> locations_pb2.ListLocationsResponse: + r"""Call the list locations method over HTTP. + + Args: + request (locations_pb2.ListLocationsRequest): + The request object for ListLocations method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + locations_pb2.ListLocationsResponse: Response from ListLocations method. + """ + + http_options = ( + _BaseToolsRestTransport._BaseListLocations._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_locations(request, metadata) + transcoded_request = ( + _BaseToolsRestTransport._BaseListLocations._get_transcoded_request( + http_options, request + ) + ) + + # Jsonify the query params + query_params = ( + _BaseToolsRestTransport._BaseListLocations._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.dialogflow_v2beta1.ToolsClient.ListLocations", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.Tools", + "rpcName": "ListLocations", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ToolsRestTransport._ListLocations._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = locations_pb2.ListLocationsResponse() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_list_locations(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.dialogflow_v2beta1.ToolsAsyncClient.ListLocations", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.Tools", + "rpcName": "ListLocations", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def cancel_operation(self): + return self._CancelOperation(self._session, self._host, self._interceptor) # type: ignore + + class _CancelOperation(_BaseToolsRestTransport._BaseCancelOperation, ToolsRestStub): + def __hash__(self): + return hash("ToolsRestTransport.CancelOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.CancelOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Call the cancel operation method over HTTP. + + Args: + request (operations_pb2.CancelOperationRequest): + The request object for CancelOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + """ + + http_options = ( + _BaseToolsRestTransport._BaseCancelOperation._get_http_options() + ) + + request, metadata = self._interceptor.pre_cancel_operation( + request, metadata + ) + transcoded_request = ( + _BaseToolsRestTransport._BaseCancelOperation._get_transcoded_request( + http_options, request + ) + ) + + # Jsonify the query params + query_params = ( + _BaseToolsRestTransport._BaseCancelOperation._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.dialogflow_v2beta1.ToolsClient.CancelOperation", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.Tools", + "rpcName": "CancelOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ToolsRestTransport._CancelOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + return self._interceptor.post_cancel_operation(None) + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(_BaseToolsRestTransport._BaseGetOperation, ToolsRestStub): + def __hash__(self): + return hash("ToolsRestTransport.GetOperation") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.GetOperationRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.Operation: + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.Operation: Response from GetOperation method. + """ + + http_options = _BaseToolsRestTransport._BaseGetOperation._get_http_options() + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + transcoded_request = ( + _BaseToolsRestTransport._BaseGetOperation._get_transcoded_request( + http_options, request + ) + ) + + # Jsonify the query params + query_params = ( + _BaseToolsRestTransport._BaseGetOperation._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.dialogflow_v2beta1.ToolsClient.GetOperation", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.Tools", + "rpcName": "GetOperation", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ToolsRestTransport._GetOperation._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.Operation() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_get_operation(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.dialogflow_v2beta1.ToolsAsyncClient.GetOperation", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.Tools", + "rpcName": "GetOperation", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(_BaseToolsRestTransport._BaseListOperations, ToolsRestStub): + def __hash__(self): + return hash("ToolsRestTransport.ListOperations") + + @staticmethod + def _get_response( + host, + metadata, + query_params, + session, + timeout, + transcoded_request, + body=None, + ): + uri = transcoded_request["uri"] + method = transcoded_request["method"] + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(session, method)( + "{host}{uri}".format(host=host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + return response + + def __call__( + self, + request: operations_pb2.ListOperationsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations method. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each value must be of type `str`, + but for metadata keys ending with the suffix `-bin`, the corresponding values must + be of type `bytes`. + + Returns: + operations_pb2.ListOperationsResponse: Response from ListOperations method. + """ + + http_options = ( + _BaseToolsRestTransport._BaseListOperations._get_http_options() + ) + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + transcoded_request = ( + _BaseToolsRestTransport._BaseListOperations._get_transcoded_request( + http_options, request + ) + ) + + # Jsonify the query params + query_params = ( + _BaseToolsRestTransport._BaseListOperations._get_query_params_json( + transcoded_request + ) + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + request_url = "{host}{uri}".format( + host=self._host, uri=transcoded_request["uri"] + ) + method = transcoded_request["method"] + try: + request_payload = json_format.MessageToJson(request) + except: + request_payload = None + http_request = { + "payload": request_payload, + "requestMethod": method, + "requestUrl": request_url, + "headers": dict(metadata), + } + _LOGGER.debug( + f"Sending request for google.cloud.dialogflow_v2beta1.ToolsClient.ListOperations", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.Tools", + "rpcName": "ListOperations", + "httpRequest": http_request, + "metadata": http_request["headers"], + }, + ) + + # Send the request + response = ToolsRestTransport._ListOperations._get_response( + self._host, + metadata, + query_params, + self._session, + timeout, + transcoded_request, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + content = response.content.decode("utf-8") + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(content, resp) + resp = self._interceptor.post_list_operations(resp) + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + logging.DEBUG + ): # pragma: NO COVER + try: + response_payload = json_format.MessageToJson(resp) + except: + response_payload = None + http_response = { + "payload": response_payload, + "headers": dict(response.headers), + "status": response.status_code, + } + _LOGGER.debug( + "Received response for google.cloud.dialogflow_v2beta1.ToolsAsyncClient.ListOperations", + extra={ + "serviceName": "google.cloud.dialogflow.v2beta1.Tools", + "rpcName": "ListOperations", + "httpResponse": http_response, + "metadata": http_response["headers"], + }, + ) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__ = ("ToolsRestTransport",) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/transports/rest_base.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/transports/rest_base.py new file mode 100644 index 000000000000..5eeca57a94e0 --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/tools/transports/rest_base.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 json # type: ignore +import re +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1, path_template +from google.cloud.location import locations_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.protobuf import json_format + +from google.cloud.dialogflow_v2beta1.types import tool +from google.cloud.dialogflow_v2beta1.types import tool as gcd_tool + +from .base import DEFAULT_CLIENT_INFO, ToolsTransport + + +class _BaseToolsRestTransport(ToolsTransport): + """Base REST backend transport for Tools. + + Note: This class is not meant to be used directly. Use its sync and + async sub-classes instead. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends JSON representations of protocol buffers over HTTP/1.1 + """ + + def __init__( + self, + *, + host: str = "dialogflow.googleapis.com", + credentials: Optional[Any] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + url_scheme: str = "https", + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + Args: + host (Optional[str]): + The hostname to connect to (default: 'dialogflow.googleapis.com'). + credentials (Optional[Any]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you are developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + url_scheme: the protocol scheme for the API endpoint. Normally + "https", but for testing or local servers, + "http" can be specified. + """ + # Run the base constructor + maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host) + if maybe_url_match is None: + raise ValueError( + f"Unexpected hostname structure: {host}" + ) # pragma: NO COVER + + url_match_items = maybe_url_match.groupdict() + + host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host + + super().__init__( + host=host, + credentials=credentials, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + class _BaseCreateTool: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2beta1/{parent=projects/*/locations/*}/tools", + "body": "tool", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = gcd_tool.CreateToolRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseToolsRestTransport._BaseCreateTool._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseDeleteTool: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v2beta1/{name=projects/*/locations/*/tools/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = tool.DeleteToolRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseToolsRestTransport._BaseDeleteTool._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetTool: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2beta1/{name=projects/*/locations/*/tools/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = tool.GetToolRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseToolsRestTransport._BaseGetTool._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseListTools: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2beta1/{parent=projects/*/locations/*}/tools", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = tool.ListToolsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseToolsRestTransport._BaseListTools._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseUpdateTool: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "patch", + "uri": "/v2beta1/{tool.name=projects/*/locations/*/tools/*}", + "body": "tool", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + pb_request = gcd_tool.UpdateToolRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + return transcoded_request + + @staticmethod + def _get_request_body_json(transcoded_request): + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + return body + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update( + _BaseToolsRestTransport._BaseUpdateTool._get_unset_required_fields( + query_params + ) + ) + + query_params["$alt"] = "json;enum-encoding=int" + return query_params + + class _BaseGetLocation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2beta1/{name=projects/*/locations/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseListLocations: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2beta1/{name=projects/*}/locations", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseCancelOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v2beta1/{name=projects/*/operations/*}:cancel", + }, + { + "method": "post", + "uri": "/v2beta1/{name=projects/*/locations/*/operations/*}:cancel", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseGetOperation: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2beta1/{name=projects/*/operations/*}", + }, + { + "method": "get", + "uri": "/v2beta1/{name=projects/*/locations/*/operations/*}", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + class _BaseListOperations: + def __hash__(self): # pragma: NO COVER + return NotImplementedError("__hash__ must be implemented.") + + @staticmethod + def _get_http_options(): + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v2beta1/{name=projects/*}/operations", + }, + { + "method": "get", + "uri": "/v2beta1/{name=projects/*/locations/*}/operations", + }, + ] + return http_options + + @staticmethod + def _get_transcoded_request(http_options, request): + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode(http_options, **request_kwargs) + return transcoded_request + + @staticmethod + def _get_query_params_json(transcoded_request): + query_params = json.loads(json.dumps(transcoded_request["query_params"])) + return query_params + + +__all__ = ("_BaseToolsRestTransport",) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/__init__.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/__init__.py index 430896050d3a..a8e1f9c6de33 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/__init__.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/__init__.py @@ -28,6 +28,7 @@ SubAgent, TrainAgentRequest, ) +from .agent_coaching_instruction import AgentCoachingInstruction from .answer_record import ( AgentAssistantFeedback, AgentAssistantRecord, @@ -41,6 +42,7 @@ from .audio_config import ( AudioEncoding, BargeInConfig, + CustomPronunciationParams, InputAudioConfig, OutputAudioConfig, OutputAudioEncoding, @@ -162,6 +164,8 @@ from .fulfillment import Fulfillment, GetFulfillmentRequest, UpdateFulfillmentRequest from .gcs import GcsDestination, GcsSource, GcsSources from .generator import ( + AgentCoachingContext, + AgentCoachingSuggestion, ConversationContext, CreateGeneratorRequest, DeleteGeneratorRequest, @@ -175,6 +179,8 @@ ListGeneratorsRequest, ListGeneratorsResponse, MessageEntry, + RaiSettings, + SuggestionDedupingConfig, SummarizationContext, SummarizationSection, SummarizationSectionList, @@ -182,6 +188,17 @@ TriggerEvent, UpdateGeneratorRequest, ) +from .generator_evaluation import ( + CreateGeneratorEvaluationRequest, + DeleteGeneratorEvaluationRequest, + EvaluationStatus, + GeneratorEvaluation, + GeneratorEvaluationConfig, + GetGeneratorEvaluationRequest, + ListGeneratorEvaluationsRequest, + ListGeneratorEvaluationsResponse, + SummarizationEvaluationMetrics, +) from .human_agent_assistant_event import HumanAgentAssistantEvent from .intent import ( BatchDeleteIntentsRequest, @@ -206,6 +223,7 @@ ListKnowledgeBasesResponse, UpdateKnowledgeBaseRequest, ) +from .operations import GeneratorEvaluationOperationMetadata from .participant import ( AnalyzeContentRequest, AnalyzeContentResponse, @@ -214,6 +232,8 @@ AssistQueryParameters, AudioInput, AutomatedAgentReply, + BidiStreamingAnalyzeContentRequest, + BidiStreamingAnalyzeContentResponse, CompileSuggestionRequest, CompileSuggestionResponse, CreateParticipantRequest, @@ -297,6 +317,16 @@ SipTrunk, UpdateSipTrunkRequest, ) +from .tool import ( + CreateToolRequest, + DeleteToolRequest, + GetToolRequest, + ListToolsRequest, + ListToolsResponse, + Tool, + UpdateToolRequest, +) +from .tool_call import ToolCall, ToolCallResult from .validation_result import ValidationError, ValidationResult from .version import ( CreateVersionRequest, @@ -323,6 +353,7 @@ "SetAgentRequest", "SubAgent", "TrainAgentRequest", + "AgentCoachingInstruction", "AgentAssistantFeedback", "AgentAssistantRecord", "AnswerFeedback", @@ -332,6 +363,7 @@ "ListAnswerRecordsResponse", "UpdateAnswerRecordRequest", "BargeInConfig", + "CustomPronunciationParams", "InputAudioConfig", "OutputAudioConfig", "SpeechContext", @@ -442,6 +474,8 @@ "GcsDestination", "GcsSource", "GcsSources", + "AgentCoachingContext", + "AgentCoachingSuggestion", "ConversationContext", "CreateGeneratorRequest", "DeleteGeneratorRequest", @@ -455,12 +489,23 @@ "ListGeneratorsRequest", "ListGeneratorsResponse", "MessageEntry", + "RaiSettings", + "SuggestionDedupingConfig", "SummarizationContext", "SummarizationSection", "SummarizationSectionList", "SummarySuggestion", "UpdateGeneratorRequest", "TriggerEvent", + "CreateGeneratorEvaluationRequest", + "DeleteGeneratorEvaluationRequest", + "EvaluationStatus", + "GeneratorEvaluation", + "GeneratorEvaluationConfig", + "GetGeneratorEvaluationRequest", + "ListGeneratorEvaluationsRequest", + "ListGeneratorEvaluationsResponse", + "SummarizationEvaluationMetrics", "HumanAgentAssistantEvent", "BatchDeleteIntentsRequest", "BatchUpdateIntentsRequest", @@ -481,6 +526,7 @@ "ListKnowledgeBasesRequest", "ListKnowledgeBasesResponse", "UpdateKnowledgeBaseRequest", + "GeneratorEvaluationOperationMetadata", "AnalyzeContentRequest", "AnalyzeContentResponse", "AnnotatedMessagePart", @@ -488,6 +534,8 @@ "AssistQueryParameters", "AudioInput", "AutomatedAgentReply", + "BidiStreamingAnalyzeContentRequest", + "BidiStreamingAnalyzeContentResponse", "CompileSuggestionRequest", "CompileSuggestionResponse", "CreateParticipantRequest", @@ -562,6 +610,15 @@ "ListSipTrunksResponse", "SipTrunk", "UpdateSipTrunkRequest", + "CreateToolRequest", + "DeleteToolRequest", + "GetToolRequest", + "ListToolsRequest", + "ListToolsResponse", + "Tool", + "UpdateToolRequest", + "ToolCall", + "ToolCallResult", "ValidationError", "ValidationResult", "CreateVersionRequest", diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/agent_coaching_instruction.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/agent_coaching_instruction.py new file mode 100644 index 000000000000..5a62c8db72d1 --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/agent_coaching_instruction.py @@ -0,0 +1,131 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.dialogflow.v2beta1", + manifest={ + "AgentCoachingInstruction", + }, +) + + +class AgentCoachingInstruction(proto.Message): + r"""Agent Coaching instructions that customer can configure. + + Attributes: + display_name (str): + Optional. Display name for the instruction. + display_details (str): + Optional. The detailed description of this + instruction. + condition (str): + Optional. The condition of the instruction. + For example, "the customer wants to cancel an + order". If the users want the instruction to be + triggered unconditionally, the condition can be + empty. + agent_action (str): + Optional. The action that human agent should take. For + example, "apologize for the slow shipping". If the users + only want to use agent coaching for intent detection, + agent_action can be empty + system_action (str): + Optional. The action that system should take. For example, + "call GetOrderTime with order_number={order number provided + by the customer}". If the users don't have plugins or don't + want to trigger plugins, the system_action can be empty + duplicate_check_result (google.cloud.dialogflow_v2beta1.types.AgentCoachingInstruction.DuplicateCheckResult): + Output only. Duplication check for the + AgentCoachingInstruction. + """ + + class DuplicateCheckResult(proto.Message): + r"""Duplication check for the suggestion. + + Attributes: + duplicate_suggestions (MutableSequence[google.cloud.dialogflow_v2beta1.types.AgentCoachingInstruction.DuplicateCheckResult.DuplicateSuggestion]): + Output only. The duplicate suggestions. + """ + + class DuplicateSuggestion(proto.Message): + r"""The duplicate suggestion details. + + Attributes: + answer_record (str): + Output only. The answer record id of the past + duplicate suggestion. + suggestion_index (int): + Output only. The index of the duplicate + suggestion in the past suggestion list. + similarity_score (float): + Output only. The similarity score of between + the past and current suggestion. + """ + + answer_record: str = proto.Field( + proto.STRING, + number=1, + ) + suggestion_index: int = proto.Field( + proto.INT32, + number=3, + ) + similarity_score: float = proto.Field( + proto.FLOAT, + number=4, + ) + + duplicate_suggestions: MutableSequence[ + "AgentCoachingInstruction.DuplicateCheckResult.DuplicateSuggestion" + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="AgentCoachingInstruction.DuplicateCheckResult.DuplicateSuggestion", + ) + + display_name: str = proto.Field( + proto.STRING, + number=1, + ) + display_details: str = proto.Field( + proto.STRING, + number=2, + ) + condition: str = proto.Field( + proto.STRING, + number=3, + ) + agent_action: str = proto.Field( + proto.STRING, + number=4, + ) + system_action: str = proto.Field( + proto.STRING, + number=5, + ) + duplicate_check_result: DuplicateCheckResult = proto.Field( + proto.MESSAGE, + number=8, + message=DuplicateCheckResult, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/answer_record.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/answer_record.py index 896322910b7a..3debb5fdaa6b 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/answer_record.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/answer_record.py @@ -21,7 +21,7 @@ from google.protobuf import timestamp_pb2 # type: ignore import proto # type: ignore -from google.cloud.dialogflow_v2beta1.types import participant +from google.cloud.dialogflow_v2beta1.types import generator, participant __protobuf__ = proto.module( package="google.cloud.dialogflow.v2beta1", @@ -128,6 +128,10 @@ class AgentAssistantRecord(proto.Message): dialogflow_assist_answer (google.cloud.dialogflow_v2beta1.types.DialogflowAssistAnswer): Output only. The Dialogflow assist answer. + This field is a member of `oneof`_ ``answer``. + generator_suggestion (google.cloud.dialogflow_v2beta1.types.GeneratorSuggestion): + Output only. The generator suggestion. + This field is a member of `oneof`_ ``answer``. """ @@ -149,6 +153,12 @@ class AgentAssistantRecord(proto.Message): oneof="answer", message=participant.DialogflowAssistAnswer, ) + generator_suggestion: generator.GeneratorSuggestion = proto.Field( + proto.MESSAGE, + number=8, + oneof="answer", + message=generator.GeneratorSuggestion, + ) class AnswerFeedback(proto.Message): diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/audio_config.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/audio_config.py index 4c74a7282598..4a8d7eb78a58 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/audio_config.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/audio_config.py @@ -34,6 +34,7 @@ "InputAudioConfig", "VoiceSelectionParams", "SynthesizeSpeechConfig", + "CustomPronunciationParams", "OutputAudioConfig", "TelephonyDtmfEvents", "SpeechToTextConfig", @@ -449,7 +450,9 @@ class InputAudioConfig(proto.Message): Support `__ for a list of the currently supported language codes. Note that queries in the same session do not necessarily need to - specify the same language. + specify the same language. If not set, the language is + inferred from the + [ConversationProfile.stt_config][google.cloud.dialogflow.v2beta1.ConversationProfile.stt_config]. enable_word_info (bool): If ``true``, Dialogflow returns [SpeechWordInfo][google.cloud.dialogflow.v2beta1.SpeechWordInfo] @@ -660,6 +663,9 @@ class SynthesizeSpeechConfig(proto.Message): voice (google.cloud.dialogflow_v2beta1.types.VoiceSelectionParams): Optional. The desired voice of the synthesized audio. + pronunciations (MutableSequence[google.cloud.dialogflow_v2beta1.types.CustomPronunciationParams]): + Optional. The custom pronunciations for the + synthesized audio. """ speaking_rate: float = proto.Field( @@ -683,6 +689,59 @@ class SynthesizeSpeechConfig(proto.Message): number=4, message="VoiceSelectionParams", ) + pronunciations: MutableSequence["CustomPronunciationParams"] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message="CustomPronunciationParams", + ) + + +class CustomPronunciationParams(proto.Message): + r"""Pronunciation customization for a phrase. + + Attributes: + phrase (str): + The phrase to which the customization is + applied. The phrase can be multiple words, such + as proper nouns, but shouldn't span the length + of the sentence. + phonetic_encoding (google.cloud.dialogflow_v2beta1.types.CustomPronunciationParams.PhoneticEncoding): + The phonetic encoding of the phrase. + pronunciation (str): + The pronunciation of the phrase. This must be + in the phonetic encoding specified above. + """ + + class PhoneticEncoding(proto.Enum): + r"""The phonetic encoding of the phrase. + + Values: + PHONETIC_ENCODING_UNSPECIFIED (0): + Not specified. + PHONETIC_ENCODING_IPA (1): + IPA, such as apple -> ˈæpəl. + https://en.wikipedia.org/wiki/International_Phonetic_Alphabet + PHONETIC_ENCODING_X_SAMPA (2): + X-SAMPA, such as apple -> "{p@l". + https://en.wikipedia.org/wiki/X-SAMPA + """ + PHONETIC_ENCODING_UNSPECIFIED = 0 + PHONETIC_ENCODING_IPA = 1 + PHONETIC_ENCODING_X_SAMPA = 2 + + phrase: str = proto.Field( + proto.STRING, + number=1, + ) + phonetic_encoding: PhoneticEncoding = proto.Field( + proto.ENUM, + number=2, + enum=PhoneticEncoding, + ) + pronunciation: str = proto.Field( + proto.STRING, + number=3, + ) class OutputAudioConfig(proto.Message): @@ -795,7 +854,10 @@ class SpeechToTextConfig(proto.Message): Support `__ for a list of the currently supported language codes. Note that queries in the same session do not necessarily need to - specify the same language. + specify the same language. If not specified, the default + language configured at + [ConversationProfile][google.cloud.dialogflow.v2beta1.ConversationProfile] + is used. enable_word_info (bool): If ``true``, Dialogflow returns [SpeechWordInfo][google.cloud.dialogflow.v2beta1.SpeechWordInfo] diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/conversation.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/conversation.py index 8bd09c9a3222..d000e760fabd 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/conversation.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/conversation.py @@ -159,7 +159,7 @@ class TelephonyConnectionInfo(proto.Message): this call in E.164 format. sdp (str): Optional. SDP of the call. It's initially the - SDP answer to the endpoint, but maybe later + SDP answer to the incoming call, but maybe later updated for the purpose of making the link active, etc. sip_headers (MutableSequence[google.cloud.dialogflow_v2beta1.types.Conversation.TelephonyConnectionInfo.SipHeader]): @@ -280,6 +280,11 @@ class ContextContent(proto.Message): Output only. The time when this information was incorporated into the relevant context reference. + answer_record (str): + If the context content was generated from a tool call, + specify the answer record associated with the tool call. + Format: + ``projects//locations//answerRecords/``. """ class ContentFormat(proto.Enum): @@ -311,6 +316,10 @@ class ContentFormat(proto.Enum): number=3, message=timestamp_pb2.Timestamp, ) + answer_record: str = proto.Field( + proto.STRING, + number=4, + ) context_contents: MutableSequence[ "Conversation.ContextReference.ContextContent" @@ -1052,6 +1061,15 @@ class GenerateStatelessSuggestionRequest(proto.Message): Optional. A list of trigger events. Generator will be triggered only if it's trigger event is included here. + security_settings (str): + Optional. Name of the CX SecuritySettings which is used to + redact generated response. If this field is empty, try to + fetch v2 security_settings, which is a project level + setting. If this field is empty and no v2 security_settings + set up in this project, no redaction will be done. + + Format: + ``projects//locations//securitySettings/``. """ parent: str = proto.Field( @@ -1087,6 +1105,10 @@ class GenerateStatelessSuggestionRequest(proto.Message): number=6, enum=gcd_generator.TriggerEvent, ) + security_settings: str = proto.Field( + proto.STRING, + number=8, + ) class GenerateStatelessSuggestionResponse(proto.Message): diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/conversation_profile.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/conversation_profile.py index 23e59ba7097b..d4a2ec7c63d7 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/conversation_profile.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/conversation_profile.py @@ -22,7 +22,7 @@ from google.protobuf import timestamp_pb2 # type: ignore import proto # type: ignore -from google.cloud.dialogflow_v2beta1.types import audio_config, participant +from google.cloud.dialogflow_v2beta1.types import audio_config, generator, participant __protobuf__ = proto.module( package="google.cloud.dialogflow.v2beta1", @@ -313,6 +313,20 @@ class SuggestionFeatureConfig(proto.Message): enable_query_suggestion_only (bool): Optional. Enable query suggestion only. Supported features: KNOWLEDGE_ASSIST + enable_response_debug_info (bool): + Optional. Enable returning detailed reasons for suggestion + results. + + For example, with this field disabled, Knowledge Search + feature returns NotFound error when no answer is found for + the input query. Enabling this field will change the + behavior to return an OK response with detailed information + indicating the lack of results. + + Supported features: KNOWLEDGE_SEARCH, KNOWLEDGE_ASSIST + rai_settings (google.cloud.dialogflow_v2beta1.types.RaiSettings): + Optional. Settings for Responsible AI checks. Supported + features: KNOWLEDGE_ASSIST suggestion_trigger_settings (google.cloud.dialogflow_v2beta1.types.HumanAgentAssistantConfig.SuggestionTriggerSettings): Settings of suggestion trigger. @@ -351,6 +365,15 @@ class SuggestionFeatureConfig(proto.Message): proto.BOOL, number=17, ) + enable_response_debug_info: bool = proto.Field( + proto.BOOL, + number=18, + ) + rai_settings: generator.RaiSettings = proto.Field( + proto.MESSAGE, + number=19, + message=generator.RaiSettings, + ) suggestion_trigger_settings: "HumanAgentAssistantConfig.SuggestionTriggerSettings" = proto.Field( proto.MESSAGE, number=10, @@ -404,6 +427,22 @@ class SuggestionConfig(proto.Message): configured and enable_event_based_suggestion must be set to true to receive the responses from high latency features in Pub/Sub. High latency feature(s): KNOWLEDGE_ASSIST + skip_empty_event_based_suggestion (bool): + Optional. Enable skipping event based + suggestion if the suggestion is empty. + + For example, with this field disabled, Knowledge + Assist feature sends a Pub/Sub message when + there are no suggestions. Enabling this field + will change the behavior to skip the Pub/Sub + message in this situation. + use_unredacted_conversation_data (bool): + Optional. If true, use unredacted transcript data (Supported + features: AI_COACH) and use unredacted ingested context + (Supported features: All Agent Assist features) + enable_async_tool_call (bool): + Optional. If true, enable asynchronous + execution of tools. """ feature_configs: MutableSequence[ @@ -425,6 +464,18 @@ class SuggestionConfig(proto.Message): proto.BOOL, number=5, ) + skip_empty_event_based_suggestion: bool = proto.Field( + proto.BOOL, + number=6, + ) + use_unredacted_conversation_data: bool = proto.Field( + proto.BOOL, + number=8, + ) + enable_async_tool_call: bool = proto.Field( + proto.BOOL, + number=9, + ) class SuggestionQueryConfig(proto.Message): r"""Config for suggestion query. @@ -722,9 +773,16 @@ class ConversationModelConfig(proto.Message): baseline_model_version (str): Version of current baseline model. It will be ignored if [model][google.cloud.dialogflow.v2beta1.HumanAgentAssistantConfig.ConversationModelConfig.model] - is set. Valid versions are: Article Suggestion baseline - model: - 0.9 - 1.0 (default) Summarization baseline model: - - 1.0 + is set. Valid versions are: + + - Article Suggestion baseline model: + + - 0.9 + - 1.0 (default) + + - Summarization baseline model: + + - 1.0 """ model: str = proto.Field( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/document.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/document.py index e1ac6abd9fdd..ace0a4169bac 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/document.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/document.py @@ -587,6 +587,8 @@ class KnowledgeOperationMetadata(proto.Message): as the destination of export. This field is a member of `oneof`_ ``operation_metadata``. + done_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the operation finished. """ class State(proto.Enum): @@ -623,6 +625,11 @@ class State(proto.Enum): oneof="operation_metadata", message="ExportOperationMetadata", ) + done_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) class ReloadDocumentRequest(proto.Message): diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/generator.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/generator.py index 4ff85cc13348..0df7fc0c405c 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/generator.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/generator.py @@ -21,6 +21,9 @@ from google.protobuf import timestamp_pb2 # type: ignore import proto # type: ignore +from google.cloud.dialogflow_v2beta1.types import agent_coaching_instruction +from google.cloud.dialogflow_v2beta1.types import tool_call as gcd_tool_call + __protobuf__ = proto.module( package="google.cloud.dialogflow.v2beta1", manifest={ @@ -36,13 +39,17 @@ "SummarizationSectionList", "FewShotExample", "InferenceParameter", + "AgentCoachingContext", "SummarizationSection", "SummarizationContext", "FreeFormContext", "Generator", "FreeFormSuggestion", "SummarySuggestion", + "AgentCoachingSuggestion", "GeneratorSuggestion", + "SuggestionDedupingConfig", + "RaiSettings", }, ) @@ -430,6 +437,45 @@ class InferenceParameter(proto.Message): ) +class AgentCoachingContext(proto.Message): + r"""Agent Coaching context that customer can configure. + + Attributes: + overarching_guidance (str): + Optional. The overarching guidance for the + agent coaching. This should be set only for v1.5 + and later versions. + instructions (MutableSequence[google.cloud.dialogflow_v2beta1.types.AgentCoachingInstruction]): + Optional. Customized instructions for agent + coaching. + version (str): + Optional. Version of the feature. If not set, default to + latest version. Current candidates are ["2.5"]. + output_language_code (str): + Optional. Output language code. + """ + + overarching_guidance: str = proto.Field( + proto.STRING, + number=7, + ) + instructions: MutableSequence[ + agent_coaching_instruction.AgentCoachingInstruction + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=agent_coaching_instruction.AgentCoachingInstruction, + ) + version: str = proto.Field( + proto.STRING, + number=2, + ) + output_language_code: str = proto.Field( + proto.STRING, + number=9, + ) + + class SummarizationSection(proto.Message): r"""Represents the section of summarization. @@ -589,6 +635,10 @@ class Generator(proto.Message): free_form_context (google.cloud.dialogflow_v2beta1.types.FreeFormContext): Input of free from generator to LLM. + This field is a member of `oneof`_ ``context``. + agent_coaching_context (google.cloud.dialogflow_v2beta1.types.AgentCoachingContext): + Input of Agent Coaching feature. + This field is a member of `oneof`_ ``context``. summarization_context (google.cloud.dialogflow_v2beta1.types.SummarizationContext): Input of Summarization feature. @@ -614,6 +664,14 @@ class Generator(proto.Message): Output only. Creation time of this generator. update_time (google.protobuf.timestamp_pb2.Timestamp): Output only. Update time of this generator. + tools (MutableSequence[str]): + Optional. Resource names of the tools that the generator can + choose from. Format: + ``projects//locations//tools/``. + suggestion_deduping_config (google.cloud.dialogflow_v2beta1.types.SuggestionDedupingConfig): + Optional. Configuration for suggestion + deduping. This is only applicable to AI Coach + feature. """ name: str = proto.Field( @@ -630,6 +688,12 @@ class Generator(proto.Message): oneof="context", message="FreeFormContext", ) + agent_coaching_context: "AgentCoachingContext" = proto.Field( + proto.MESSAGE, + number=12, + oneof="context", + message="AgentCoachingContext", + ) summarization_context: "SummarizationContext" = proto.Field( proto.MESSAGE, number=13, @@ -661,6 +725,15 @@ class Generator(proto.Message): number=9, message=timestamp_pb2.Timestamp, ) + tools: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=14, + ) + suggestion_deduping_config: "SuggestionDedupingConfig" = proto.Field( + proto.MESSAGE, + number=23, + message="SuggestionDedupingConfig", + ) class FreeFormSuggestion(proto.Message): @@ -711,6 +784,170 @@ class SummarySection(proto.Message): ) +class AgentCoachingSuggestion(proto.Message): + r"""Suggestion for coaching agents. + + Attributes: + applicable_instructions (MutableSequence[google.cloud.dialogflow_v2beta1.types.AgentCoachingInstruction]): + Optional. Instructions applicable based on + the current context. + agent_action_suggestions (MutableSequence[google.cloud.dialogflow_v2beta1.types.AgentCoachingSuggestion.AgentActionSuggestion]): + Optional. Suggested actions for the agent to + take. + sample_responses (MutableSequence[google.cloud.dialogflow_v2beta1.types.AgentCoachingSuggestion.SampleResponse]): + Optional. Sample response for the Agent. + """ + + class Sources(proto.Message): + r"""Sources for the suggestion. + + Attributes: + instruction_indexes (MutableSequence[int]): + Output only. Source instruction indexes for the suggestion. + This is the index of the applicable_instructions field. + """ + + instruction_indexes: MutableSequence[int] = proto.RepeatedField( + proto.INT32, + number=2, + ) + + class DuplicateCheckResult(proto.Message): + r"""Duplication check for the suggestion. + + Attributes: + duplicate_suggestions (MutableSequence[google.cloud.dialogflow_v2beta1.types.AgentCoachingSuggestion.DuplicateCheckResult.DuplicateSuggestion]): + Output only. The duplicate suggestions. + """ + + class DuplicateSuggestion(proto.Message): + r"""The duplicate suggestion details. Keeping answer_record and sources + together as they are identifiers for duplicate suggestions. + + Attributes: + answer_record (str): + Output only. The answer record id of the past + duplicate suggestion. + sources (google.cloud.dialogflow_v2beta1.types.AgentCoachingSuggestion.Sources): + Output only. Sources for the suggestion. + suggestion_index (int): + Output only. The index of the duplicate + suggestion in the past suggestion list. + similarity_score (float): + Output only. The similarity score of between + the past and current suggestion. + """ + + answer_record: str = proto.Field( + proto.STRING, + number=1, + ) + sources: "AgentCoachingSuggestion.Sources" = proto.Field( + proto.MESSAGE, + number=2, + message="AgentCoachingSuggestion.Sources", + ) + suggestion_index: int = proto.Field( + proto.INT32, + number=3, + ) + similarity_score: float = proto.Field( + proto.FLOAT, + number=4, + ) + + duplicate_suggestions: MutableSequence[ + "AgentCoachingSuggestion.DuplicateCheckResult.DuplicateSuggestion" + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="AgentCoachingSuggestion.DuplicateCheckResult.DuplicateSuggestion", + ) + + class AgentActionSuggestion(proto.Message): + r"""Actions suggested for the agent. This is based on applicable + instructions. + + Attributes: + agent_action (str): + Optional. The suggested action for the agent. + sources (google.cloud.dialogflow_v2beta1.types.AgentCoachingSuggestion.Sources): + Output only. Sources for the agent action + suggestion. + duplicate_check_result (google.cloud.dialogflow_v2beta1.types.AgentCoachingSuggestion.DuplicateCheckResult): + Output only. Duplicate check result for the + agent action suggestion. + """ + + agent_action: str = proto.Field( + proto.STRING, + number=1, + ) + sources: "AgentCoachingSuggestion.Sources" = proto.Field( + proto.MESSAGE, + number=2, + message="AgentCoachingSuggestion.Sources", + ) + duplicate_check_result: "AgentCoachingSuggestion.DuplicateCheckResult" = ( + proto.Field( + proto.MESSAGE, + number=3, + message="AgentCoachingSuggestion.DuplicateCheckResult", + ) + ) + + class SampleResponse(proto.Message): + r"""Sample response that the agent can use. This could be based + on applicable instructions and ingested data from other systems. + + Attributes: + response_text (str): + Optional. Sample response for Agent in text. + sources (google.cloud.dialogflow_v2beta1.types.AgentCoachingSuggestion.Sources): + Output only. Sources for the Sample Response. + duplicate_check_result (google.cloud.dialogflow_v2beta1.types.AgentCoachingSuggestion.DuplicateCheckResult): + Output only. Duplicate check result for the + sample response. + """ + + response_text: str = proto.Field( + proto.STRING, + number=1, + ) + sources: "AgentCoachingSuggestion.Sources" = proto.Field( + proto.MESSAGE, + number=2, + message="AgentCoachingSuggestion.Sources", + ) + duplicate_check_result: "AgentCoachingSuggestion.DuplicateCheckResult" = ( + proto.Field( + proto.MESSAGE, + number=3, + message="AgentCoachingSuggestion.DuplicateCheckResult", + ) + ) + + applicable_instructions: MutableSequence[ + agent_coaching_instruction.AgentCoachingInstruction + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=agent_coaching_instruction.AgentCoachingInstruction, + ) + agent_action_suggestions: MutableSequence[ + AgentActionSuggestion + ] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=AgentActionSuggestion, + ) + sample_responses: MutableSequence[SampleResponse] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=SampleResponse, + ) + + class GeneratorSuggestion(proto.Message): r"""Suggestion generated using a Generator. @@ -730,8 +967,36 @@ class GeneratorSuggestion(proto.Message): Optional. Suggested summary. This field is a member of `oneof`_ ``suggestion``. + agent_coaching_suggestion (google.cloud.dialogflow_v2beta1.types.AgentCoachingSuggestion): + Optional. Suggestion to coach the agent. + + This field is a member of `oneof`_ ``suggestion``. + tool_call_info (MutableSequence[google.cloud.dialogflow_v2beta1.types.GeneratorSuggestion.ToolCallInfo]): + Optional. List of request and response for + tool calls executed. """ + class ToolCallInfo(proto.Message): + r"""Request and response for a tool call. + + Attributes: + tool_call (google.cloud.dialogflow_v2beta1.types.ToolCall): + Required. Request for a tool call. + tool_call_result (google.cloud.dialogflow_v2beta1.types.ToolCallResult): + Required. Response for a tool call. + """ + + tool_call: gcd_tool_call.ToolCall = proto.Field( + proto.MESSAGE, + number=1, + message=gcd_tool_call.ToolCall, + ) + tool_call_result: gcd_tool_call.ToolCallResult = proto.Field( + proto.MESSAGE, + number=2, + message=gcd_tool_call.ToolCallResult, + ) + free_form_suggestion: "FreeFormSuggestion" = proto.Field( proto.MESSAGE, number=1, @@ -744,6 +1009,125 @@ class GeneratorSuggestion(proto.Message): oneof="suggestion", message="SummarySuggestion", ) + agent_coaching_suggestion: "AgentCoachingSuggestion" = proto.Field( + proto.MESSAGE, + number=3, + oneof="suggestion", + message="AgentCoachingSuggestion", + ) + tool_call_info: MutableSequence[ToolCallInfo] = proto.RepeatedField( + proto.MESSAGE, + number=9, + message=ToolCallInfo, + ) + + +class SuggestionDedupingConfig(proto.Message): + r"""Config for suggestion deduping. NEXT_ID: 3 + + Attributes: + enable_deduping (bool): + Optional. Whether to enable suggestion + deduping. + similarity_threshold (float): + Optional. The threshold for similarity between two + suggestions. Acceptable value is [0.0, 1.0], default to 0.8 + """ + + enable_deduping: bool = proto.Field( + proto.BOOL, + number=1, + ) + similarity_threshold: float = proto.Field( + proto.FLOAT, + number=2, + ) + + +class RaiSettings(proto.Message): + r"""Settings for Responsible AI checks. + + Attributes: + rai_category_configs (MutableSequence[google.cloud.dialogflow_v2beta1.types.RaiSettings.RaiCategoryConfig]): + Configuration for a set of RAI categories. + """ + + class RaiCategoryConfig(proto.Message): + r"""Configuration for a specific RAI category. + + Attributes: + category (google.cloud.dialogflow_v2beta1.types.RaiSettings.RaiCategoryConfig.RaiCategory): + Optional. The RAI category. + sensitivity_level (google.cloud.dialogflow_v2beta1.types.RaiSettings.RaiCategoryConfig.SensitivityLevel): + Optional. The sensitivity level for this + category. + """ + + class RaiCategory(proto.Enum): + r"""Enum for RAI category. + + Values: + RAI_CATEGORY_UNSPECIFIED (0): + Default value. + DANGEROUS_CONTENT (1): + Dangerous content. + SEXUALLY_EXPLICIT (2): + Sexually explicit content. + HARASSMENT (3): + Harassment content. + HATE_SPEECH (4): + Hate speech content. + """ + RAI_CATEGORY_UNSPECIFIED = 0 + DANGEROUS_CONTENT = 1 + SEXUALLY_EXPLICIT = 2 + HARASSMENT = 3 + HATE_SPEECH = 4 + + class SensitivityLevel(proto.Enum): + r"""Enum for user-configurable sensitivity levels. + + Values: + SENSITIVITY_LEVEL_UNSPECIFIED (0): + Default value. If unspecified, the default behavior is: + + - DANGEROUS_CONTENT: BLOCK_FEW + - SEXUALLY_EXPLICIT: BLOCK_SOME + - HARASSMENT: BLOCK_SOME + - HATE_SPEECH: BLOCK_SOME + BLOCK_MOST (1): + Block most potentially sensitive responses. + BLOCK_SOME (2): + Block some potentially sensitive responses. + BLOCK_FEW (3): + Block a few potentially sensitive responses. + BLOCK_NONE (4): + No filtering for this category. + """ + SENSITIVITY_LEVEL_UNSPECIFIED = 0 + BLOCK_MOST = 1 + BLOCK_SOME = 2 + BLOCK_FEW = 3 + BLOCK_NONE = 4 + + category: "RaiSettings.RaiCategoryConfig.RaiCategory" = proto.Field( + proto.ENUM, + number=1, + enum="RaiSettings.RaiCategoryConfig.RaiCategory", + ) + sensitivity_level: "RaiSettings.RaiCategoryConfig.SensitivityLevel" = ( + proto.Field( + proto.ENUM, + number=2, + enum="RaiSettings.RaiCategoryConfig.SensitivityLevel", + ) + ) + + rai_category_configs: MutableSequence[RaiCategoryConfig] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=RaiCategoryConfig, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/generator_evaluation.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/generator_evaluation.py new file mode 100644 index 000000000000..bb1a90d849d1 --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/generator_evaluation.py @@ -0,0 +1,1032 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +import proto # type: ignore + +from google.cloud.dialogflow_v2beta1.types import generator + +__protobuf__ = proto.module( + package="google.cloud.dialogflow.v2beta1", + manifest={ + "CreateGeneratorEvaluationRequest", + "GetGeneratorEvaluationRequest", + "ListGeneratorEvaluationsRequest", + "ListGeneratorEvaluationsResponse", + "DeleteGeneratorEvaluationRequest", + "GeneratorEvaluation", + "SummarizationEvaluationMetrics", + "GeneratorEvaluationConfig", + "EvaluationStatus", + }, +) + + +class CreateGeneratorEvaluationRequest(proto.Message): + r"""Request of CreateGeneratorEvaluation. + + Attributes: + parent (str): + Required. The generator resource name. Format: + ``projects//locations//generators/`` + generator_evaluation (google.cloud.dialogflow_v2beta1.types.GeneratorEvaluation): + Required. The generator evaluation to be + created. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + generator_evaluation: "GeneratorEvaluation" = proto.Field( + proto.MESSAGE, + number=2, + message="GeneratorEvaluation", + ) + + +class GetGeneratorEvaluationRequest(proto.Message): + r"""Request of GetGeneratorEvaluation. + + Attributes: + name (str): + Required. The generator evaluation resource name. Format: + ``projects//locations//generators//evaluations/`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListGeneratorEvaluationsRequest(proto.Message): + r"""Request of ListGeneratorEvaluations. + + Attributes: + parent (str): + Required. The generator resource name. Format: + ``projects//locations//generators/`` + Wildcard value ``-`` is supported on generator_id to list + evaluations across all generators under same project. + page_size (int): + Optional. Maximum number of evaluations to + return in a single page. By default 100 and at + most 1000. + page_token (str): + Optional. The next_page_token value returned from a previous + list request. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListGeneratorEvaluationsResponse(proto.Message): + r"""Response of ListGeneratorEvaluations. + + Attributes: + generator_evaluations (MutableSequence[google.cloud.dialogflow_v2beta1.types.GeneratorEvaluation]): + The list of evaluations to return. + next_page_token (str): + Token to retrieve the next page of results, + or empty if there are no more results in the + list. + """ + + @property + def raw_page(self): + return self + + generator_evaluations: MutableSequence["GeneratorEvaluation"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="GeneratorEvaluation", + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class DeleteGeneratorEvaluationRequest(proto.Message): + r"""Request of DeleteGeneratorEvaluation. + + Attributes: + name (str): + Required. The generator evaluation resource name. Format: + ``projects//locations//generators// evaluations/`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GeneratorEvaluation(proto.Message): + r"""Represents evaluation result of a generator. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + Output only. Identifier. The resource name of the + evaluation. Format: + ``projects//locations//generators// evaluations/`` + display_name (str): + Optional. The display name of the generator + evaluation. At most 64 bytes long. + generator_evaluation_config (google.cloud.dialogflow_v2beta1.types.GeneratorEvaluationConfig): + Required. The configuration of the evaluation + task. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Creation time of this generator + evaluation. + complete_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Completion time of this + generator evaluation. + initial_generator (google.cloud.dialogflow_v2beta1.types.Generator): + Required. The initial generator that was used + when creating this evaluation. This is a copy of + the generator read from storage when creating + the evaluation. + summarization_metrics (google.cloud.dialogflow_v2beta1.types.SummarizationEvaluationMetrics): + Output only. Only available when the + summarization generator is provided. + + This field is a member of `oneof`_ ``metrics``. + evaluation_status (google.cloud.dialogflow_v2beta1.types.EvaluationStatus): + Output only. The result status of the + evaluation pipeline. Provides the status + information including if the evaluation is still + in progress, completed or failed with certain + error and user actionable message. + satisfies_pzs (bool): + Output only. A read only boolean field + reflecting Zone Separation status of the model. + The field is an aggregated value of ZS status of + its underlying dependencies. See more details in + go/zicy-resource-placement#resource-status + + This field is a member of `oneof`_ ``_satisfies_pzs``. + satisfies_pzi (bool): + Output only. A read only boolean field + reflecting Zone Isolation status of the model. + The field is an aggregated value of ZI status of + its underlying dependencies. See more details in + go/zicy-resource-placement#resource-status + + This field is a member of `oneof`_ ``_satisfies_pzi``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + generator_evaluation_config: "GeneratorEvaluationConfig" = proto.Field( + proto.MESSAGE, + number=3, + message="GeneratorEvaluationConfig", + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + complete_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=8, + message=timestamp_pb2.Timestamp, + ) + initial_generator: generator.Generator = proto.Field( + proto.MESSAGE, + number=5, + message=generator.Generator, + ) + summarization_metrics: "SummarizationEvaluationMetrics" = proto.Field( + proto.MESSAGE, + number=6, + oneof="metrics", + message="SummarizationEvaluationMetrics", + ) + evaluation_status: "EvaluationStatus" = proto.Field( + proto.MESSAGE, + number=10, + message="EvaluationStatus", + ) + satisfies_pzs: bool = proto.Field( + proto.BOOL, + number=11, + optional=True, + ) + satisfies_pzi: bool = proto.Field( + proto.BOOL, + number=12, + optional=True, + ) + + +class SummarizationEvaluationMetrics(proto.Message): + r"""Evaluation metrics for summarization generator. + + Attributes: + summarization_evaluation_results (MutableSequence[google.cloud.dialogflow_v2beta1.types.SummarizationEvaluationMetrics.SummarizationEvaluationResult]): + Output only. A list of evaluation results per + conversation(&summary), metric and section. + summarization_evaluation_merged_results_uri (str): + Output only. User bucket uri for merged + evaluation score and aggregation score csv. + overall_metrics (MutableSequence[google.cloud.dialogflow_v2beta1.types.SummarizationEvaluationMetrics.OverallScoresByMetric]): + Output only. A list of aggregated(average) + scores per metric section. + overall_section_tokens (MutableSequence[google.cloud.dialogflow_v2beta1.types.SummarizationEvaluationMetrics.SectionToken]): + Output only. Overall token per section. This + is an aggregated(sum) result of input token of + summary acorss all conversations that are + selected for summarization evaluation. + conversation_details (MutableSequence[google.cloud.dialogflow_v2beta1.types.SummarizationEvaluationMetrics.ConversationDetail]): + Output only. List of conversation details. + """ + + class AccuracyDecomposition(proto.Message): + r"""Decomposition details for accuracy. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + point (str): + Output only. The breakdown point of the + summary. + accuracy_reasoning (str): + Output only. The accuracy reasoning of the + breakdown point. + is_accurate (bool): + Output only. Whether the breakdown point is + accurate or not. + + This field is a member of `oneof`_ ``_is_accurate``. + """ + + point: str = proto.Field( + proto.STRING, + number=1, + ) + accuracy_reasoning: str = proto.Field( + proto.STRING, + number=2, + ) + is_accurate: bool = proto.Field( + proto.BOOL, + number=3, + optional=True, + ) + + class AdherenceDecomposition(proto.Message): + r"""Decomposition details for adherence. + + Attributes: + point (str): + Output only. The breakdown point of the given + instructions. + adherence_reasoning (str): + Output only. The adherence reasoning of the + breakdown point. + is_adherent (bool): + Output only. Whether the breakdown point is + adherent or not. + """ + + point: str = proto.Field( + proto.STRING, + number=1, + ) + adherence_reasoning: str = proto.Field( + proto.STRING, + number=2, + ) + is_adherent: bool = proto.Field( + proto.BOOL, + number=3, + ) + + class AdherenceRubric(proto.Message): + r"""Rubric result of the adherence evaluation. A rubric is ued to + determine if the summary adheres to all aspects of the given + instructions. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + question (str): + Output only. The question generated from + instruction that used to evaluate summary. + reasoning (str): + Output only. The reasoning of the rubric + question is addressed or not. + is_addressed (bool): + Output only. A boolean that indicates whether + the rubric question is addressed or not. + + This field is a member of `oneof`_ ``_is_addressed``. + """ + + question: str = proto.Field( + proto.STRING, + number=1, + ) + reasoning: str = proto.Field( + proto.STRING, + number=2, + ) + is_addressed: bool = proto.Field( + proto.BOOL, + number=3, + optional=True, + ) + + class CompletenessRubric(proto.Message): + r"""Rubric details of the completeness evaluation result. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + question (str): + Output only. The question generated from + instruction that used to evaluate summary. + is_addressed (bool): + Output only. A boolean that indicates whether + the rubric question is addressed or not. + + This field is a member of `oneof`_ ``_is_addressed``. + """ + + question: str = proto.Field( + proto.STRING, + number=1, + ) + is_addressed: bool = proto.Field( + proto.BOOL, + number=2, + optional=True, + ) + + class Decomposition(proto.Message): + r"""Decomposition details + + 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: + accuracy_decomposition (google.cloud.dialogflow_v2beta1.types.SummarizationEvaluationMetrics.AccuracyDecomposition): + only available for accuracy metric. + + This field is a member of `oneof`_ ``decomposition``. + adherence_decomposition (google.cloud.dialogflow_v2beta1.types.SummarizationEvaluationMetrics.AdherenceDecomposition): + only available for adherence metric. + + This field is a member of `oneof`_ ``decomposition``. + """ + + accuracy_decomposition: "SummarizationEvaluationMetrics.AccuracyDecomposition" = proto.Field( + proto.MESSAGE, + number=1, + oneof="decomposition", + message="SummarizationEvaluationMetrics.AccuracyDecomposition", + ) + adherence_decomposition: "SummarizationEvaluationMetrics.AdherenceDecomposition" = proto.Field( + proto.MESSAGE, + number=2, + oneof="decomposition", + message="SummarizationEvaluationMetrics.AdherenceDecomposition", + ) + + class EvaluationResult(proto.Message): + r"""Evaluation result that contains one of accuracy, adherence or + completeness evaluation result. + + 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: + accuracy_decomposition (google.cloud.dialogflow_v2beta1.types.SummarizationEvaluationMetrics.AccuracyDecomposition): + Only available for accuracy metric. + + This field is a member of `oneof`_ ``result``. + adherence_rubric (google.cloud.dialogflow_v2beta1.types.SummarizationEvaluationMetrics.AdherenceRubric): + Only available for adherence metric. + + This field is a member of `oneof`_ ``result``. + completeness_rubric (google.cloud.dialogflow_v2beta1.types.SummarizationEvaluationMetrics.CompletenessRubric): + Only available for completeness metric. + + This field is a member of `oneof`_ ``result``. + """ + + accuracy_decomposition: "SummarizationEvaluationMetrics.AccuracyDecomposition" = proto.Field( + proto.MESSAGE, + number=1, + oneof="result", + message="SummarizationEvaluationMetrics.AccuracyDecomposition", + ) + adherence_rubric: "SummarizationEvaluationMetrics.AdherenceRubric" = ( + proto.Field( + proto.MESSAGE, + number=2, + oneof="result", + message="SummarizationEvaluationMetrics.AdherenceRubric", + ) + ) + completeness_rubric: "SummarizationEvaluationMetrics.CompletenessRubric" = ( + proto.Field( + proto.MESSAGE, + number=3, + oneof="result", + message="SummarizationEvaluationMetrics.CompletenessRubric", + ) + ) + + class SummarizationEvaluationResult(proto.Message): + r"""Evaluation result per conversation(&summary), metric and + section. + + Attributes: + session_id (str): + Output only. conversation session id + metric (str): + Output only. metric name, e.g. accuracy, + completeness, adherence, etc. + section (str): + Output only. section/task name, e.g. action, + situation, etc + score (float): + Output only. score calculated from + decompositions + section_summary (str): + Output only. Summary of this section + decompositions (MutableSequence[google.cloud.dialogflow_v2beta1.types.SummarizationEvaluationMetrics.Decomposition]): + Output only. List of decompostion details + evaluation_results (MutableSequence[google.cloud.dialogflow_v2beta1.types.SummarizationEvaluationMetrics.EvaluationResult]): + Output only. List of evaluation results. + """ + + session_id: str = proto.Field( + proto.STRING, + number=1, + ) + metric: str = proto.Field( + proto.STRING, + number=2, + ) + section: str = proto.Field( + proto.STRING, + number=3, + ) + score: float = proto.Field( + proto.FLOAT, + number=4, + ) + section_summary: str = proto.Field( + proto.STRING, + number=6, + ) + decompositions: MutableSequence[ + "SummarizationEvaluationMetrics.Decomposition" + ] = proto.RepeatedField( + proto.MESSAGE, + number=7, + message="SummarizationEvaluationMetrics.Decomposition", + ) + evaluation_results: MutableSequence[ + "SummarizationEvaluationMetrics.EvaluationResult" + ] = proto.RepeatedField( + proto.MESSAGE, + number=8, + message="SummarizationEvaluationMetrics.EvaluationResult", + ) + + class OverallScoresByMetric(proto.Message): + r"""Overall performance per metric. This is the aggregated score + for each metric across all conversations that are selected for + summarization evaluation. + + Attributes: + metric (str): + Output only. Metric name. e.g. accuracy, + adherence, completeness. + """ + + metric: str = proto.Field( + proto.STRING, + number=1, + ) + + class SectionToken(proto.Message): + r"""A pair of section name and input token count of the input + summary section. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + section (str): + Output only. The name of the summary + instruction. + token_count (int): + Output only. Token count. + + This field is a member of `oneof`_ ``_token_count``. + """ + + section: str = proto.Field( + proto.STRING, + number=1, + ) + token_count: int = proto.Field( + proto.INT64, + number=2, + optional=True, + ) + + class ConversationDetail(proto.Message): + r"""Aggregated evaluation result on conversation level. This + contains evaluation results of all the metrics and sections. + + Attributes: + message_entries (MutableSequence[google.cloud.dialogflow_v2beta1.types.MessageEntry]): + Output only. Conversation transcript that + used for summarization evaluation as a + reference. + summary_sections (MutableSequence[google.cloud.dialogflow_v2beta1.types.SummarySuggestion.SummarySection]): + Output only. Summary sections that used for + summarization evaluation as a reference. + metric_details (MutableSequence[google.cloud.dialogflow_v2beta1.types.SummarizationEvaluationMetrics.ConversationDetail.MetricDetail]): + Output only. List of metric details. + section_tokens (MutableSequence[google.cloud.dialogflow_v2beta1.types.SummarizationEvaluationMetrics.SectionToken]): + Output only. Conversation level token count + per section. This is an aggregated(sum) result + of input token of summary acorss all metrics for + a single conversation. + """ + + class MetricDetail(proto.Message): + r"""Aggregated result on metric level. This contains the + evaluation results of all the sections. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + metric (str): + Output only. Metrics name. e.g. accuracy, + adherence, completeness. + score (float): + Output only. Aggregated(average) score on + this metric across all sections. + + This field is a member of `oneof`_ ``_score``. + section_details (MutableSequence[google.cloud.dialogflow_v2beta1.types.SummarizationEvaluationMetrics.ConversationDetail.MetricDetail.SectionDetail]): + Output only. List of section details. + """ + + class SectionDetail(proto.Message): + r"""Section level result. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + section (str): + Output only. The name of the summary + instruction. + score (float): + Output only. Aggregated(average) score on + this section across all evaluation results. + Either decompositions or rubrics. + + This field is a member of `oneof`_ ``_score``. + section_summary (str): + Output only. Summary for this section + evaluation_results (MutableSequence[google.cloud.dialogflow_v2beta1.types.SummarizationEvaluationMetrics.EvaluationResult]): + Output only. List of evaluation result. The + list only contains one kind of the evaluation + result. + """ + + section: str = proto.Field( + proto.STRING, + number=1, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + optional=True, + ) + section_summary: str = proto.Field( + proto.STRING, + number=4, + ) + evaluation_results: MutableSequence[ + "SummarizationEvaluationMetrics.EvaluationResult" + ] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message="SummarizationEvaluationMetrics.EvaluationResult", + ) + + metric: str = proto.Field( + proto.STRING, + number=1, + ) + score: float = proto.Field( + proto.FLOAT, + number=2, + optional=True, + ) + section_details: MutableSequence[ + "SummarizationEvaluationMetrics.ConversationDetail.MetricDetail.SectionDetail" + ] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message="SummarizationEvaluationMetrics.ConversationDetail.MetricDetail.SectionDetail", + ) + + message_entries: MutableSequence[generator.MessageEntry] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=generator.MessageEntry, + ) + summary_sections: MutableSequence[ + generator.SummarySuggestion.SummarySection + ] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=generator.SummarySuggestion.SummarySection, + ) + metric_details: MutableSequence[ + "SummarizationEvaluationMetrics.ConversationDetail.MetricDetail" + ] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="SummarizationEvaluationMetrics.ConversationDetail.MetricDetail", + ) + section_tokens: MutableSequence[ + "SummarizationEvaluationMetrics.SectionToken" + ] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message="SummarizationEvaluationMetrics.SectionToken", + ) + + summarization_evaluation_results: MutableSequence[ + SummarizationEvaluationResult + ] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=SummarizationEvaluationResult, + ) + summarization_evaluation_merged_results_uri: str = proto.Field( + proto.STRING, + number=5, + ) + overall_metrics: MutableSequence[OverallScoresByMetric] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message=OverallScoresByMetric, + ) + overall_section_tokens: MutableSequence[SectionToken] = proto.RepeatedField( + proto.MESSAGE, + number=7, + message=SectionToken, + ) + conversation_details: MutableSequence[ConversationDetail] = proto.RepeatedField( + proto.MESSAGE, + number=8, + message=ConversationDetail, + ) + + +class GeneratorEvaluationConfig(proto.Message): + r"""Generator evaluation input config. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + input_data_config (google.cloud.dialogflow_v2beta1.types.GeneratorEvaluationConfig.InputDataConfig): + Required. The config/source of input data. + output_gcs_bucket_path (str): + Required. The output Cloud Storage bucket path to store eval + files, e.g. per_summary_accuracy_score report. This path is + provided by customer and files stored in it are visible to + customer, no internal data should be stored in this path. + summarization_config (google.cloud.dialogflow_v2beta1.types.GeneratorEvaluationConfig.SummarizationConfig): + Evaluation configs for summarization + generator. + + This field is a member of `oneof`_ ``evaluation_feature_config``. + """ + + class InputDataSourceType(proto.Enum): + r"""Enumeration of input data source type. + + Values: + INPUT_DATA_SOURCE_TYPE_UNSPECIFIED (0): + Unspecified InputDataSourceType. Should not + be used. + AGENT_ASSIST_CONVERSATIONS (1): + Fetch data from Agent Assist storage. If this source type is + chosen, input_data_config.start_time and + input_data_config.end_timestamp must be provided. + INSIGHTS_CONVERSATIONS (2): + Fetch data from Insights storage. If this source type is + chosen, input_data_config.start_time and + input_data_config.end_timestamp must be provided. + """ + INPUT_DATA_SOURCE_TYPE_UNSPECIFIED = 0 + AGENT_ASSIST_CONVERSATIONS = 1 + INSIGHTS_CONVERSATIONS = 2 + + class AgentAssistInputDataConfig(proto.Message): + r"""The distinctive configs for Agent Assist conversations as the + conversation source. + + Attributes: + start_time (google.protobuf.timestamp_pb2.Timestamp): + Required. The start of the time range for + conversations to be evaluated. Only + conversations created at or after this timestamp + will be sampled. + end_time (google.protobuf.timestamp_pb2.Timestamp): + Required. The end of the time range for + conversations to be evaluated. Only + conversations ended at or before this timestamp + will be sampled. + """ + + start_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + + class DatasetInputDataConfig(proto.Message): + r"""The distinctive configs for dataset as the conversation + source. + + Attributes: + dataset (str): + Required. The identifier of the dataset to be evaluated. + Format: + ``projects//locations//datasets/``. + """ + + dataset: str = proto.Field( + proto.STRING, + number=1, + ) + + class InputDataConfig(proto.Message): + r"""Input data config details + + 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: + input_data_source_type (google.cloud.dialogflow_v2beta1.types.GeneratorEvaluationConfig.InputDataSourceType): + Required. The source type of input data. + start_time (google.protobuf.timestamp_pb2.Timestamp): + Optional. The start timestamp to fetch + conversation data. + end_time (google.protobuf.timestamp_pb2.Timestamp): + Optional. The end timestamp to fetch + conversation data. + sample_size (int): + Optional. Desired number of + conversation-summary pairs to be evaluated. + is_summary_generation_allowed (bool): + Optional. Whether the summary generation is + allowed when the pre-existing qualified + summaries are insufficient to cover the sample + size. + summary_generation_option (google.cloud.dialogflow_v2beta1.types.GeneratorEvaluationConfig.InputDataConfig.SummaryGenerationOption): + Optional. Option to control whether summaries + are generated during evaluation. + agent_assist_input_data_config (google.cloud.dialogflow_v2beta1.types.GeneratorEvaluationConfig.AgentAssistInputDataConfig): + The distinctive configs for Agent Assist + conversations as the conversation source. + + This field is a member of `oneof`_ ``source_specific_config``. + dataset_input_data_config (google.cloud.dialogflow_v2beta1.types.GeneratorEvaluationConfig.DatasetInputDataConfig): + The distinctive configs for dataset as the + conversation source. + + This field is a member of `oneof`_ ``source_specific_config``. + """ + + class SummaryGenerationOption(proto.Enum): + r"""Summary generation options. + + Values: + SUMMARY_GENERATION_OPTION_UNSPECIFIED (0): + Default option will not be used + ALWAYS_GENERATE (1): + Always Generate summary for all + conversations. + GENERATE_IF_MISSING (2): + Gnerate only missing summaries. + DO_NOT_GENERATE (3): + Do not generate new summaries. Only use + existing summaries found. + """ + SUMMARY_GENERATION_OPTION_UNSPECIFIED = 0 + ALWAYS_GENERATE = 1 + GENERATE_IF_MISSING = 2 + DO_NOT_GENERATE = 3 + + input_data_source_type: "GeneratorEvaluationConfig.InputDataSourceType" = ( + proto.Field( + proto.ENUM, + number=1, + enum="GeneratorEvaluationConfig.InputDataSourceType", + ) + ) + start_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + sample_size: int = proto.Field( + proto.INT32, + number=4, + ) + is_summary_generation_allowed: bool = proto.Field( + proto.BOOL, + number=5, + ) + summary_generation_option: "GeneratorEvaluationConfig.InputDataConfig.SummaryGenerationOption" = proto.Field( + proto.ENUM, + number=8, + enum="GeneratorEvaluationConfig.InputDataConfig.SummaryGenerationOption", + ) + agent_assist_input_data_config: "GeneratorEvaluationConfig.AgentAssistInputDataConfig" = proto.Field( + proto.MESSAGE, + number=6, + oneof="source_specific_config", + message="GeneratorEvaluationConfig.AgentAssistInputDataConfig", + ) + dataset_input_data_config: "GeneratorEvaluationConfig.DatasetInputDataConfig" = proto.Field( + proto.MESSAGE, + number=7, + oneof="source_specific_config", + message="GeneratorEvaluationConfig.DatasetInputDataConfig", + ) + + class SummarizationConfig(proto.Message): + r"""Evaluation configs for summarization generator. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + enable_accuracy_evaluation (bool): + Optional. Enable accuracy evaluation. + accuracy_evaluation_version (str): + Optional. Version for summarization accuracy. + This will determine the prompt and model used at + backend. + enable_completeness_evaluation (bool): + Optional. Enable completeness evaluation. + completeness_evaluation_version (str): + Optional. Version for summarization + completeness. This will determine the prompt and + model used at backend. + evaluator_version (str): + Output only. Version for summarization + evaluation. + + This field is a member of `oneof`_ ``_evaluator_version``. + """ + + enable_accuracy_evaluation: bool = proto.Field( + proto.BOOL, + number=1, + ) + accuracy_evaluation_version: str = proto.Field( + proto.STRING, + number=2, + ) + enable_completeness_evaluation: bool = proto.Field( + proto.BOOL, + number=3, + ) + completeness_evaluation_version: str = proto.Field( + proto.STRING, + number=4, + ) + evaluator_version: str = proto.Field( + proto.STRING, + number=5, + optional=True, + ) + + input_data_config: InputDataConfig = proto.Field( + proto.MESSAGE, + number=1, + message=InputDataConfig, + ) + output_gcs_bucket_path: str = proto.Field( + proto.STRING, + number=2, + ) + summarization_config: SummarizationConfig = proto.Field( + proto.MESSAGE, + number=3, + oneof="evaluation_feature_config", + message=SummarizationConfig, + ) + + +class EvaluationStatus(proto.Message): + r"""A common evalaution pipeline status. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + done (bool): + Output only. If the value is ``false``, it means the + evaluation is still in progress. If ``true``, the operation + is completed, and either ``error`` or ``response`` is + available. + + This field is a member of `oneof`_ ``_done``. + pipeline_status (google.rpc.status_pb2.Status): + Output only. The error result of the + evaluation in case of failure in evaluation + pipeline. + """ + + done: bool = proto.Field( + proto.BOOL, + number=1, + optional=True, + ) + pipeline_status: status_pb2.Status = proto.Field( + proto.MESSAGE, + number=2, + message=status_pb2.Status, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/operations.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/operations.py new file mode 100644 index 000000000000..188bc3f1cc9e --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/operations.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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 MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.dialogflow.v2beta1", + manifest={ + "GeneratorEvaluationOperationMetadata", + }, +) + + +class GeneratorEvaluationOperationMetadata(proto.Message): + r"""Metadata for a + [GeneratorEvaluations.CreateGeneratorEvaluation][google.cloud.dialogflow.v2beta1.GeneratorEvaluations.CreateGeneratorEvaluation] + operation. + + Attributes: + generator_evaluation (str): + Output only. The resource name of the generator evaluation. + Format: + ``projects//locations//generators//evaluations/`` + """ + + generator_evaluation: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/participant.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/participant.py index 6f5aaf0872e8..87e575b036c0 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/participant.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/participant.py @@ -74,6 +74,8 @@ "SuggestKnowledgeAssistRequest", "SuggestKnowledgeAssistResponse", "KnowledgeAssistAnswer", + "BidiStreamingAnalyzeContentRequest", + "BidiStreamingAnalyzeContentResponse", }, ) @@ -585,51 +587,59 @@ class AutomatedAgentReplyType(proto.Enum): class SuggestionInput(proto.Message): - r"""Represents the selection of a suggestion. + r"""Represents the action to take for a tool call that requires + confirmation. Attributes: answer_record (str): - Required. The ID of a suggestion selected by the human - agent. The suggestion(s) were generated in a previous call - to request Dialogflow assist. The format is: + Required. Format: ``projects//locations//answerRecords/`` - where is an alphanumeric string. + The answer record associated with the tool call. text_override (google.cloud.dialogflow_v2beta1.types.TextInput): Optional. If the customer edited the suggestion before using it, include the revised text here. parameters (google.protobuf.struct_pb2.Struct): - In Dialogflow assist for v3, the user can submit a form by - sending a - [SuggestionInput][google.cloud.dialogflow.v2beta1.SuggestionInput]. - The form is uniquely determined by the - [answer_record][google.cloud.dialogflow.v2beta1.SuggestionInput.answer_record] - field, which identifies a v3 - [QueryResult][google.cloud.dialogflow.v3alpha1.QueryResult] - containing the current - [page][google.cloud.dialogflow.v3alpha1.Page]. The form - parameters are specified via the - [parameters][google.cloud.dialogflow.v2beta1.SuggestionInput.parameters] - field. - - Depending on your protocol or client library language, this - is a map, associative array, symbol table, dictionary, or - JSON object composed of a collection of (MapKey, MapValue) - pairs: - - - MapKey type: string - - MapKey value: parameter name - - MapValue type: If parameter's entity type is a composite - entity then use map, otherwise, depending on the parameter - value type, it could be one of string, number, boolean, - null, list or map. - - MapValue value: If parameter's entity type is a composite - entity then use map from composite entity property names - to property values, otherwise, use parameter value. + Parameters to be used for the tool call. If + not provided, the tool will be called without + any parameters. + action (google.cloud.dialogflow_v2beta1.types.SuggestionInput.Action): + Optional. The type of action to take with the + tool. intent_input (google.cloud.dialogflow_v2beta1.types.IntentInput): The intent to be triggered on V3 agent. + send_time (google.protobuf.timestamp_pb2.Timestamp): + Optional. Time when the current suggest input + is sent. For tool calls, this timestamp (along + with the answer record) will be included in the + corresponding tool call result so that it can be + identified. """ + class Action(proto.Enum): + r"""Indicate what type of action to take with the tool call. + + Values: + ACTION_UNSPECIFIED (0): + Action not specified. + CANCEL (1): + Indicates the user chooses to not make the + tool call. It is only applicable to tool calls + that are waiting for user confirmation. + REVISE (2): + Makes the tool call with provided parameters. + This action is intended for tool calls that only + read but not write data. + CONFIRM (3): + Makes the tool call with provided parameters. + This action is intended for tool calls that may + write data. + """ + ACTION_UNSPECIFIED = 0 + CANCEL = 1 + REVISE = 2 + CONFIRM = 3 + answer_record: str = proto.Field( proto.STRING, number=1, @@ -644,11 +654,21 @@ class SuggestionInput(proto.Message): number=4, message=struct_pb2.Struct, ) + action: Action = proto.Field( + proto.ENUM, + number=5, + enum=Action, + ) intent_input: "IntentInput" = proto.Field( proto.MESSAGE, number=6, message="IntentInput", ) + send_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=7, + message=timestamp_pb2.Timestamp, + ) class IntentInput(proto.Message): @@ -1159,12 +1179,15 @@ class StreamingAnalyzeContentRequest(proto.Message): input_intent (str): The intent to be triggered on V3 agent. Format: ``projects//locations//locations/ /agents//intents/``. + This can only be used to trigger the Welcome intent id if + you are using text_config. This field is a member of `oneof`_ ``input``. input_event (str): The input event name. This can only be sent once and would cancel the - ongoing speech recognition if any. + ongoing speech recognition if any. To trigger + the Welcome intent use the event "WELCOME". This field is a member of `oneof`_ ``input``. query_params (google.cloud.dialogflow_v2beta1.types.QueryParameters): @@ -2938,4 +2961,298 @@ class Snippet(proto.Message): ) +class BidiStreamingAnalyzeContentRequest(proto.Message): + r"""The request message for + [Participants.BidiStreamingAnalyzeContent][google.cloud.dialogflow.v2beta1.Participants.BidiStreamingAnalyzeContent]. + + 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: + config (google.cloud.dialogflow_v2beta1.types.BidiStreamingAnalyzeContentRequest.Config): + The config message for this conversation. + + This field is a member of `oneof`_ ``request``. + input (google.cloud.dialogflow_v2beta1.types.BidiStreamingAnalyzeContentRequest.Input): + Text, audio or other multi-modality inputs. + This is the second and following messages sent + by the client. + + This field is a member of `oneof`_ ``request``. + """ + + class Config(proto.Message): + r"""The config of the session. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + participant (str): + Required. The name of the participant to fetch response for. + Format: + ``projects//locations//conversations//participants/``. + voice_session_config (google.cloud.dialogflow_v2beta1.types.BidiStreamingAnalyzeContentRequest.Config.VoiceSessionConfig): + Configure a voice-based session. + + This field is a member of `oneof`_ ``config``. + initial_virtual_agent_parameters (google.protobuf.struct_pb2.Struct): + Parameters to be passed to the virtual agent + at the beginning. + initial_virtual_agent_query_params (google.cloud.dialogflow_v2beta1.types.QueryParameters): + Initial parameters for the virtual-agent. + """ + + class VoiceSessionConfig(proto.Message): + r"""The config about how to process the audio for a voice-based + session. + + Attributes: + input_audio_encoding (google.cloud.dialogflow_v2beta1.types.AudioEncoding): + Required. The encoding of input audio. + input_audio_sample_rate_hertz (int): + Required. The sample rate of input audio. + output_audio_encoding (google.cloud.dialogflow_v2beta1.types.OutputAudioEncoding): + Required. The encoding of output audio. + output_audio_sample_rate_hertz (int): + Required. The sample rate of output audio. + enable_cx_proactive_processing (bool): + Optional. Whether to enable CX proactive + processing. + enable_streaming_synthesize (bool): + Optional. If true, Dialogflow will stream the + audio bytes from Cloud TTS for speech synthesis + using the StreamingSynthesize api. + """ + + input_audio_encoding: gcd_audio_config.AudioEncoding = proto.Field( + proto.ENUM, + number=1, + enum=gcd_audio_config.AudioEncoding, + ) + input_audio_sample_rate_hertz: int = proto.Field( + proto.INT32, + number=2, + ) + output_audio_encoding: gcd_audio_config.OutputAudioEncoding = proto.Field( + proto.ENUM, + number=3, + enum=gcd_audio_config.OutputAudioEncoding, + ) + output_audio_sample_rate_hertz: int = proto.Field( + proto.INT32, + number=4, + ) + enable_cx_proactive_processing: bool = proto.Field( + proto.BOOL, + number=5, + ) + enable_streaming_synthesize: bool = proto.Field( + proto.BOOL, + number=23, + ) + + participant: str = proto.Field( + proto.STRING, + number=1, + ) + voice_session_config: "BidiStreamingAnalyzeContentRequest.Config.VoiceSessionConfig" = proto.Field( + proto.MESSAGE, + number=2, + oneof="config", + message="BidiStreamingAnalyzeContentRequest.Config.VoiceSessionConfig", + ) + initial_virtual_agent_parameters: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=3, + message=struct_pb2.Struct, + ) + initial_virtual_agent_query_params: session.QueryParameters = proto.Field( + proto.MESSAGE, + number=4, + message=session.QueryParameters, + ) + + class TurnInput(proto.Message): + r"""Input that forms data for a single turn. + + 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: + text (str): + The UTF-8 encoded natural language text to be + processed. + + This field is a member of `oneof`_ ``main_content``. + intent (str): + The intent to be triggered on V3 agent. Format: + ``projects//locations//locations/ /agents//intents/``. + This can only be used to trigger the Welcome intent id if + the modality is text. + + This field is a member of `oneof`_ ``main_content``. + event (str): + The input event name. + This can only be sent once and would cancel the + ongoing speech recognition if any. To trigger + the Welcome intent use the event "WELCOME". + + This field is a member of `oneof`_ ``main_content``. + virtual_agent_parameters (google.protobuf.struct_pb2.Struct): + Optional. Parameters to be passed to the + virtual agent. + """ + + text: str = proto.Field( + proto.STRING, + number=1, + oneof="main_content", + ) + intent: str = proto.Field( + proto.STRING, + number=2, + oneof="main_content", + ) + event: str = proto.Field( + proto.STRING, + number=3, + oneof="main_content", + ) + virtual_agent_parameters: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=4, + message=struct_pb2.Struct, + ) + + class Input(proto.Message): + r"""Input for the conversation. + + 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: + audio (bytes): + The content of audio stream to be recognized. + + This field is a member of `oneof`_ ``input``. + dtmf (google.cloud.dialogflow_v2beta1.types.TelephonyDtmfEvents): + The DTMF digits used to invoke intent and + fill in parameter value. + This input is ignored if the previous response + indicated that DTMF input is not accepted. + + This field is a member of `oneof`_ ``input``. + turn (google.cloud.dialogflow_v2beta1.types.BidiStreamingAnalyzeContentRequest.TurnInput): + Turn input. + + This field is a member of `oneof`_ ``input``. + """ + + audio: bytes = proto.Field( + proto.BYTES, + number=1, + oneof="input", + ) + dtmf: gcd_audio_config.TelephonyDtmfEvents = proto.Field( + proto.MESSAGE, + number=2, + oneof="input", + message=gcd_audio_config.TelephonyDtmfEvents, + ) + turn: "BidiStreamingAnalyzeContentRequest.TurnInput" = proto.Field( + proto.MESSAGE, + number=3, + oneof="input", + message="BidiStreamingAnalyzeContentRequest.TurnInput", + ) + + config: Config = proto.Field( + proto.MESSAGE, + number=1, + oneof="request", + message=Config, + ) + input: Input = proto.Field( + proto.MESSAGE, + number=2, + oneof="request", + message=Input, + ) + + +class BidiStreamingAnalyzeContentResponse(proto.Message): + r"""The response message for + [Participants.BidiStreamingAnalyzeContent][google.cloud.dialogflow.v2beta1.Participants.BidiStreamingAnalyzeContent]. + + 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: + recognition_result (google.cloud.dialogflow_v2beta1.types.StreamingRecognitionResult): + The result of speech recognition. + + This field is a member of `oneof`_ ``response``. + barge_in_signal (google.cloud.dialogflow_v2beta1.types.BidiStreamingAnalyzeContentResponse.BargeInSignal): + Indicate the user barge-in has been detected, + and client should stop playing back the audio. + + This field is a member of `oneof`_ ``response``. + analyze_content_response (google.cloud.dialogflow_v2beta1.types.AnalyzeContentResponse): + The agent response from analyze content. + + This field is a member of `oneof`_ ``response``. + turn_complete (google.cloud.dialogflow_v2beta1.types.BidiStreamingAnalyzeContentResponse.TurnComplete): + Indicate that the turn is complete. + + This field is a member of `oneof`_ ``response``. + """ + + class BargeInSignal(proto.Message): + r"""Indicate the user barge-in has been detected.""" + + class TurnComplete(proto.Message): + r"""Indicate that the turn is complete.""" + + recognition_result: session.StreamingRecognitionResult = proto.Field( + proto.MESSAGE, + number=1, + oneof="response", + message=session.StreamingRecognitionResult, + ) + barge_in_signal: BargeInSignal = proto.Field( + proto.MESSAGE, + number=2, + oneof="response", + message=BargeInSignal, + ) + analyze_content_response: "AnalyzeContentResponse" = proto.Field( + proto.MESSAGE, + number=3, + oneof="response", + message="AnalyzeContentResponse", + ) + turn_complete: TurnComplete = proto.Field( + proto.MESSAGE, + number=4, + oneof="response", + message=TurnComplete, + ) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/session.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/session.py index 1b219ea55e76..92b40c5acb82 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/session.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/session.py @@ -1212,8 +1212,6 @@ class MessageType(proto.Enum): TRANSCRIPT (1): Message contains a (possibly partial) transcript. - DTMF_DIGITS (3): - Message contains DTMF digits. END_OF_SINGLE_UTTERANCE (2): This event indicates that the server has detected the end of the user's speech utterance and expects no additional @@ -1225,6 +1223,8 @@ class MessageType(proto.Enum): connection. This message is only sent if ``single_utterance`` was set to ``true``, and is not used otherwise. + DTMF_DIGITS (3): + Message contains DTMF digits. PARTIAL_DTMF_DIGITS (4): Message contains DTMF digits. Before a message with DTMF_DIGITS is sent, a message with PARTIAL_DTMF_DIGITS may @@ -1233,8 +1233,8 @@ class MessageType(proto.Enum): """ MESSAGE_TYPE_UNSPECIFIED = 0 TRANSCRIPT = 1 - DTMF_DIGITS = 3 END_OF_SINGLE_UTTERANCE = 2 + DTMF_DIGITS = 3 PARTIAL_DTMF_DIGITS = 4 message_type: MessageType = proto.Field( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/tool.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/tool.py new file mode 100644 index 000000000000..28648e4ed075 --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/tool.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 __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import struct_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.dialogflow.v2beta1", + manifest={ + "CreateToolRequest", + "GetToolRequest", + "ListToolsRequest", + "ListToolsResponse", + "DeleteToolRequest", + "UpdateToolRequest", + "Tool", + }, +) + + +class CreateToolRequest(proto.Message): + r"""Request message of CreateTool. + + Attributes: + parent (str): + Required. The project/location to create tool for. Format: + ``projects//locations/`` + tool (google.cloud.dialogflow_v2beta1.types.Tool): + Required. The tool to create. + tool_id (str): + Optional. The ID to use for the tool, which will become the + final component of the tool's resource name. + + The tool ID must be compliant with the regression formula + ``[a-zA-Z][a-zA-Z0-9_-]*`` with the characters length in + range of [3,64]. If the field is not provide, an Id will be + auto-generated. If the field is provided, the caller is + responsible for + + 1. the uniqueness of the ID, otherwise the request will be + rejected. + 2. the consistency for whether to use custom ID or not under + a project to better ensure uniqueness. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + tool: "Tool" = proto.Field( + proto.MESSAGE, + number=2, + message="Tool", + ) + tool_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class GetToolRequest(proto.Message): + r"""Request message of GetTool. + + Attributes: + name (str): + Required. The tool resource name to retrieve. Format: + ``projects//locations//tools/`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListToolsRequest(proto.Message): + r"""Request message of ListTools. + + Attributes: + parent (str): + Required. The project/location to list tools for. Format: + ``projects//locations/`` + page_size (int): + Optional. Maximum number of conversation + models to return in a single page. Default to + 10. + page_token (str): + Optional. The next_page_token value returned from a previous + list request. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + page_size: int = proto.Field( + proto.INT32, + number=2, + ) + page_token: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ListToolsResponse(proto.Message): + r"""Response of ListTools. + + Attributes: + tools (MutableSequence[google.cloud.dialogflow_v2beta1.types.Tool]): + List of tools retrieved. + next_page_token (str): + Token to retrieve the next page of results, + or empty if there are no more results in the + list. + """ + + @property + def raw_page(self): + return self + + tools: MutableSequence["Tool"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="Tool", + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class DeleteToolRequest(proto.Message): + r"""Request of DeleteTool. + + Attributes: + name (str): + Required. The tool resource name to delete. Format: + ``projects//locations//tools/`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class UpdateToolRequest(proto.Message): + r"""Request of UpdateTool. + + Attributes: + tool (google.cloud.dialogflow_v2beta1.types.Tool): + Required. The tool to update. + The name field of tool is to identify the tool + to update. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. The list of fields to update. + """ + + tool: "Tool" = proto.Field( + proto.MESSAGE, + number=1, + message="Tool", + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class Tool(proto.Message): + r"""Represents a tool. + + 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: + name (str): + Output only. Identifier. The resource name of the tool. + Format: + ``projects//locations//tools/``. + tool_key (str): + Required. A human readable short name of the + tool, which should be unique within the project. + It should only contain letters, numbers, and + underscores, and it will be used by LLM to + identify the tool. + display_name (str): + Optional. A human readable short name of the + tool, to be shown on the UI. + description (str): + Optional. A human readable description of the + tool. + action_confirmation_requirement (MutableMapping[str, google.cloud.dialogflow_v2beta1.types.Tool.ConfirmationRequirement]): + Optional. Confirmation requirement for the actions. Each key + is an action name in the action_schemas. If an action's + confirmation requirement is unspecified (either the key is + not present, or its value is + CONFIRMATION_REQUIREMENT_UNSPECIFIED), the requirement is + inferred from the action's method_type - confirmation is not + required if and only if method_type is GET. + extension_spec (google.cloud.dialogflow_v2beta1.types.Tool.ExtensionTool): + Vertex extension tool specification. + + This field is a member of `oneof`_ ``specification``. + function_spec (google.cloud.dialogflow_v2beta1.types.Tool.FunctionTool): + Client side executed function specification. + + This field is a member of `oneof`_ ``specification``. + connector_spec (google.cloud.dialogflow_v2beta1.types.Tool.ConnectorTool): + Integration connectors tool specification. + + This field is a member of `oneof`_ ``specification``. + open_api_spec (google.cloud.dialogflow_v2beta1.types.Tool.OpenApiTool): + OpenAPI tool. + + This field is a member of `oneof`_ ``specification``. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Creation time of this tool. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Update time of this tool. + satisfies_pzs (bool): + Output only. A read only boolean field + reflecting Zone Separation status of the tool. + If the field is absent, it means the status is + unknown. + + This field is a member of `oneof`_ ``_satisfies_pzs``. + satisfies_pzi (bool): + Output only. A read only boolean field + reflecting Zone Isolation status of the tool. If + the field is absent, it means the status is + unknown. + + This field is a member of `oneof`_ ``_satisfies_pzi``. + """ + + class ConfirmationRequirement(proto.Enum): + r"""Types of confirmation requirement. + + Values: + CONFIRMATION_REQUIREMENT_UNSPECIFIED (0): + Unspecified. Whether the action requires confirmation is + inferred from method_type. + REQUIRED (1): + Conformation is required. + NOT_REQUIRED (2): + Conformation is not required. + """ + CONFIRMATION_REQUIREMENT_UNSPECIFIED = 0 + REQUIRED = 1 + NOT_REQUIRED = 2 + + class MethodType(proto.Enum): + r"""The method type of the function. + + Values: + METHOD_TYPE_UNSPECIFIED (0): + Unspecified. + GET (1): + GET method. + POST (2): + POST method. + PUT (3): + PUT method. + DELETE (4): + DELETE method. + PATCH (5): + PATCH method. + """ + METHOD_TYPE_UNSPECIFIED = 0 + GET = 1 + POST = 2 + PUT = 3 + DELETE = 4 + PATCH = 5 + + class ExtensionTool(proto.Message): + r"""An ExtensionTool is a way to use Vertex Extensions as a tool. + + Attributes: + name (str): + Required. The full name of the referenced vertex extension. + Format: + ``projects/{project}/locations/{location}/extensions/{extension}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + class FunctionTool(proto.Message): + r"""A Function tool describes the functions to be invoked on the + client side. + + Attributes: + input_schema (google.protobuf.struct_pb2.Struct): + Optional. The JSON schema is encapsulated in a + [google.protobuf.Struct][google.protobuf.Struct] to describe + the input of the function. This input is a JSON object that + contains the function's parameters as properties of the + object. + output_schema (google.protobuf.struct_pb2.Struct): + Optional. The JSON schema is encapsulated in a + [google.protobuf.Struct][google.protobuf.Struct] to describe + the output of the function. This output is a JSON object + that contains the function's parameters as properties of the + object. + method_type (google.cloud.dialogflow_v2beta1.types.Tool.MethodType): + Optional. The method type of the function. If + not specified, the default value is GET. + """ + + input_schema: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=1, + message=struct_pb2.Struct, + ) + output_schema: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=2, + message=struct_pb2.Struct, + ) + method_type: "Tool.MethodType" = proto.Field( + proto.ENUM, + number=4, + enum="Tool.MethodType", + ) + + class OpenApiTool(proto.Message): + r"""An OpenAPI tool is a way to provide the Tool specifications + in the Open API schema format. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + text_schema (str): + Required. The OpenAPI schema specified as a + text. + + This field is a member of `oneof`_ ``schema``. + authentication (google.cloud.dialogflow_v2beta1.types.Tool.Authentication): + Optional. Authentication information required + by the API. + tls_config (google.cloud.dialogflow_v2beta1.types.Tool.TLSConfig): + Optional. TLS configuration for the HTTPS + verification. + service_directory_config (google.cloud.dialogflow_v2beta1.types.Tool.ServiceDirectoryConfig): + Optional. Service Directory configuration. + """ + + text_schema: str = proto.Field( + proto.STRING, + number=1, + oneof="schema", + ) + authentication: "Tool.Authentication" = proto.Field( + proto.MESSAGE, + number=2, + message="Tool.Authentication", + ) + tls_config: "Tool.TLSConfig" = proto.Field( + proto.MESSAGE, + number=3, + message="Tool.TLSConfig", + ) + service_directory_config: "Tool.ServiceDirectoryConfig" = proto.Field( + proto.MESSAGE, + number=4, + message="Tool.ServiceDirectoryConfig", + ) + + class ConnectorTool(proto.Message): + r"""A ConnectorTool enabling using Integration Connectors + Connections as tools. + + Attributes: + name (str): + Required. The full resource name of the referenced + Integration Connectors Connection. Format: + 'projects/*/locations/*/connections/\*' + actions (MutableSequence[google.cloud.dialogflow_v2beta1.types.Tool.ConnectorTool.Action]): + Required. Actions for the tool to use. + """ + + class Action(proto.Message): + r"""Configuration of a Connection operation for the tool to use. + + 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: + connection_action_id (str): + ID of a Connection action for the tool to + use. + + This field is a member of `oneof`_ ``action_spec``. + entity_operation (google.cloud.dialogflow_v2beta1.types.Tool.ConnectorTool.Action.EntityOperation): + Entity operation configuration for the tool + to use. + + This field is a member of `oneof`_ ``action_spec``. + input_fields (MutableSequence[str]): + Optional. Entity fields to use as inputs for + the operation. If no fields are specified, all + fields of the Entity will be used. + output_fields (MutableSequence[str]): + Optional. Entity fields to return from the + operation. If no fields are specified, all + fields of the Entity will be returned. + """ + + class EntityOperation(proto.Message): + r"""Entity CRUD operation specification. + + Attributes: + entity_id (str): + Required. ID of the entity. + operation (google.cloud.dialogflow_v2beta1.types.Tool.ConnectorTool.Action.EntityOperation.OperationType): + Required. Operation to perform on the entity. + """ + + class OperationType(proto.Enum): + r"""The operation to perform on the entity. + + Values: + OPERATION_TYPE_UNSPECIFIED (0): + Operation type unspecified. Invalid, + ConnectorTool create/update will fail. + LIST (1): + List operation. + GET (2): + Get operation. + CREATE (3): + Create operation. + UPDATE (4): + Update operation. + DELETE (5): + Delete operation. + """ + OPERATION_TYPE_UNSPECIFIED = 0 + LIST = 1 + GET = 2 + CREATE = 3 + UPDATE = 4 + DELETE = 5 + + entity_id: str = proto.Field( + proto.STRING, + number=1, + ) + operation: "Tool.ConnectorTool.Action.EntityOperation.OperationType" = ( + proto.Field( + proto.ENUM, + number=2, + enum="Tool.ConnectorTool.Action.EntityOperation.OperationType", + ) + ) + + connection_action_id: str = proto.Field( + proto.STRING, + number=4, + oneof="action_spec", + ) + entity_operation: "Tool.ConnectorTool.Action.EntityOperation" = proto.Field( + proto.MESSAGE, + number=5, + oneof="action_spec", + message="Tool.ConnectorTool.Action.EntityOperation", + ) + input_fields: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + output_fields: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + name: str = proto.Field( + proto.STRING, + number=1, + ) + actions: MutableSequence["Tool.ConnectorTool.Action"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="Tool.ConnectorTool.Action", + ) + + class Authentication(proto.Message): + r"""Authentication information required for API calls + + 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: + api_key_config (google.cloud.dialogflow_v2beta1.types.Tool.Authentication.ApiKeyConfig): + Config for API key auth. + + This field is a member of `oneof`_ ``auth_config``. + oauth_config (google.cloud.dialogflow_v2beta1.types.Tool.Authentication.OAuthConfig): + Config for OAuth. + + This field is a member of `oneof`_ ``auth_config``. + service_agent_auth_config (google.cloud.dialogflow_v2beta1.types.Tool.Authentication.ServiceAgentAuthConfig): + Config for `Diglogflow service + agent `__ + auth. + + This field is a member of `oneof`_ ``auth_config``. + bearer_token_config (google.cloud.dialogflow_v2beta1.types.Tool.Authentication.BearerTokenConfig): + Config for bearer token auth. + + This field is a member of `oneof`_ ``auth_config``. + """ + + class RequestLocation(proto.Enum): + r"""The location of the API key in the request. + + Values: + REQUEST_LOCATION_UNSPECIFIED (0): + Default value. This value is unused. + HEADER (1): + Represents the key in http header. + QUERY_STRING (2): + Represents the key in query string. + """ + REQUEST_LOCATION_UNSPECIFIED = 0 + HEADER = 1 + QUERY_STRING = 2 + + class ApiKeyConfig(proto.Message): + r"""Config for authentication with API key. + + Attributes: + key_name (str): + Required. The parameter name or the header + name of the API key. E.g., If the API request is + "https://example.com/act?X-Api-Key=", + "X-Api-Key" would be the parameter name. + api_key (str): + Optional. The API key. If the ``secret_version_for_api_key`` + field is set, this field will be ignored. + secret_version_for_api_key (str): + Optional. The name of the SecretManager secret version + resource storing the API key. If this field is set, the + ``api_key`` field will be ignored. Format: + ``projects/{project}/secrets/{secret}/versions/{version}`` + request_location (google.cloud.dialogflow_v2beta1.types.Tool.Authentication.RequestLocation): + Required. Key location in the request. + """ + + key_name: str = proto.Field( + proto.STRING, + number=1, + ) + api_key: str = proto.Field( + proto.STRING, + number=2, + ) + secret_version_for_api_key: str = proto.Field( + proto.STRING, + number=4, + ) + request_location: "Tool.Authentication.RequestLocation" = proto.Field( + proto.ENUM, + number=3, + enum="Tool.Authentication.RequestLocation", + ) + + class OAuthConfig(proto.Message): + r"""Config for authentication with OAuth. + + Attributes: + oauth_grant_type (google.cloud.dialogflow_v2beta1.types.Tool.Authentication.OAuthConfig.OauthGrantType): + Required. OAuth grant types. + client_id (str): + Required. The client ID from the OAuth + provider. + client_secret (str): + Optional. The client secret from the OAuth provider. If the + ``secret_version_for_client_secret`` field is set, this + field will be ignored. + secret_version_for_client_secret (str): + Optional. The name of the SecretManager secret version + resource storing the client secret. If this field is set, + the ``client_secret`` field will be ignored. Format: + ``projects/{project}/secrets/{secret}/versions/{version}`` + token_endpoint (str): + Required. The token endpoint in the OAuth + provider to exchange for an access token. + scopes (MutableSequence[str]): + Optional. The OAuth scopes to grant. + """ + + class OauthGrantType(proto.Enum): + r"""OAuth grant types. Only `client credential + grant `__ is + supported. + + Values: + OAUTH_GRANT_TYPE_UNSPECIFIED (0): + Default value. This value is unused. + CLIENT_CREDENTIAL (1): + Represents the `client credential + flow `__. + """ + OAUTH_GRANT_TYPE_UNSPECIFIED = 0 + CLIENT_CREDENTIAL = 1 + + oauth_grant_type: "Tool.Authentication.OAuthConfig.OauthGrantType" = ( + proto.Field( + proto.ENUM, + number=1, + enum="Tool.Authentication.OAuthConfig.OauthGrantType", + ) + ) + client_id: str = proto.Field( + proto.STRING, + number=2, + ) + client_secret: str = proto.Field( + proto.STRING, + number=3, + ) + secret_version_for_client_secret: str = proto.Field( + proto.STRING, + number=6, + ) + token_endpoint: str = proto.Field( + proto.STRING, + number=4, + ) + scopes: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + + class ServiceAgentAuthConfig(proto.Message): + r"""Config for auth using `Dialogflow service + agent `__. + + Attributes: + service_agent_auth (google.cloud.dialogflow_v2beta1.types.Tool.Authentication.ServiceAgentAuthConfig.ServiceAgentAuth): + Optional. Indicate the auth token type generated from the + `Diglogflow service + agent `__. + The generated token is sent in the Authorization header. + """ + + class ServiceAgentAuth(proto.Enum): + r"""Indicate the auth token type generated from the `Diaglogflow service + agent `__. + + Values: + SERVICE_AGENT_AUTH_UNSPECIFIED (0): + Service agent auth type unspecified. Default to ID_TOKEN. + ID_TOKEN (1): + Use `ID + token `__ + generated from service agent. This can be used to access + Cloud Function and Cloud Run after you grant Invoker role to + ``service-@gcp-sa-dialogflow.iam.gserviceaccount.com``. + ACCESS_TOKEN (2): + Use `access + token `__ + generated from service agent. This can be used to access + other Google Cloud APIs after you grant required roles to + ``service-@gcp-sa-dialogflow.iam.gserviceaccount.com``. + """ + SERVICE_AGENT_AUTH_UNSPECIFIED = 0 + ID_TOKEN = 1 + ACCESS_TOKEN = 2 + + service_agent_auth: "Tool.Authentication.ServiceAgentAuthConfig.ServiceAgentAuth" = proto.Field( + proto.ENUM, + number=1, + enum="Tool.Authentication.ServiceAgentAuthConfig.ServiceAgentAuth", + ) + + class BearerTokenConfig(proto.Message): + r"""Config for authentication using bearer token. + + Attributes: + token (str): + Optional. The text token appended to the text ``Bearer`` to + the request Authorization header. `Session parameters + reference `__ + can be used to pass the token dynamically, e.g. + ``$session.params.parameter-id``. + secret_version_for_token (str): + Optional. The name of the SecretManager secret version + resource storing the Bearer token. If this field is set, the + ``token`` field will be ignored. Format: + ``projects/{project}/secrets/{secret}/versions/{version}`` + """ + + token: str = proto.Field( + proto.STRING, + number=1, + ) + secret_version_for_token: str = proto.Field( + proto.STRING, + number=2, + ) + + api_key_config: "Tool.Authentication.ApiKeyConfig" = proto.Field( + proto.MESSAGE, + number=1, + oneof="auth_config", + message="Tool.Authentication.ApiKeyConfig", + ) + oauth_config: "Tool.Authentication.OAuthConfig" = proto.Field( + proto.MESSAGE, + number=2, + oneof="auth_config", + message="Tool.Authentication.OAuthConfig", + ) + service_agent_auth_config: "Tool.Authentication.ServiceAgentAuthConfig" = ( + proto.Field( + proto.MESSAGE, + number=3, + oneof="auth_config", + message="Tool.Authentication.ServiceAgentAuthConfig", + ) + ) + bearer_token_config: "Tool.Authentication.BearerTokenConfig" = proto.Field( + proto.MESSAGE, + number=4, + oneof="auth_config", + message="Tool.Authentication.BearerTokenConfig", + ) + + class TLSConfig(proto.Message): + r"""The TLS configuration. + + Attributes: + ca_certs (MutableSequence[google.cloud.dialogflow_v2beta1.types.Tool.TLSConfig.CACert]): + Required. Specifies a list of allowed custom + CA certificates for HTTPS verification. + """ + + class CACert(proto.Message): + r"""The CA certificate. + + Attributes: + display_name (str): + Required. The name of the allowed custom CA + certificates. This can be used to disambiguate + the custom CA certificates. + cert (bytes): + Required. The allowed custom CA certificates (in DER format) + for HTTPS verification. This overrides the default SSL trust + store. If this is empty or unspecified, Dialogflow will use + Google's default trust store to verify certificates. N.B. + Make sure the HTTPS server certificates are signed with + "subject alt name". For instance a certificate can be + self-signed using the following command, + + :: + + openssl x509 -req -days 200 -in example.com.csr \ + -signkey example.com.key \ + -out example.com.crt \ + -extfile <(printf "\nsubjectAltName='DNS:www.example.com'") + """ + + display_name: str = proto.Field( + proto.STRING, + number=1, + ) + cert: bytes = proto.Field( + proto.BYTES, + number=2, + ) + + ca_certs: MutableSequence["Tool.TLSConfig.CACert"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="Tool.TLSConfig.CACert", + ) + + class ServiceDirectoryConfig(proto.Message): + r"""Configuration for tools using Service Directory. + + Attributes: + service (str): + Required. The name of `Service + Directory `__ + service. Format: + ``projects//locations//namespaces//services/``. + ``LocationID`` of the service directory must be the same as + the location of the tool. + """ + + service: str = proto.Field( + proto.STRING, + number=1, + ) + + name: str = proto.Field( + proto.STRING, + number=1, + ) + tool_key: str = proto.Field( + proto.STRING, + number=2, + ) + display_name: str = proto.Field( + proto.STRING, + number=19, + ) + description: str = proto.Field( + proto.STRING, + number=3, + ) + action_confirmation_requirement: MutableMapping[ + str, ConfirmationRequirement + ] = proto.MapField( + proto.STRING, + proto.ENUM, + number=17, + enum=ConfirmationRequirement, + ) + extension_spec: ExtensionTool = proto.Field( + proto.MESSAGE, + number=4, + oneof="specification", + message=ExtensionTool, + ) + function_spec: FunctionTool = proto.Field( + proto.MESSAGE, + number=13, + oneof="specification", + message=FunctionTool, + ) + connector_spec: ConnectorTool = proto.Field( + proto.MESSAGE, + number=18, + oneof="specification", + message=ConnectorTool, + ) + open_api_spec: OpenApiTool = proto.Field( + proto.MESSAGE, + number=20, + oneof="specification", + message=OpenApiTool, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + satisfies_pzs: bool = proto.Field( + proto.BOOL, + number=14, + optional=True, + ) + satisfies_pzi: bool = proto.Field( + proto.BOOL, + number=15, + optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/tool_call.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/tool_call.py new file mode 100644 index 000000000000..79d54ee9cbac --- /dev/null +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/types/tool_call.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 __future__ import annotations + +from typing import MutableMapping, MutableSequence + +from google.protobuf import struct_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.dialogflow.v2beta1", + manifest={ + "ToolCall", + "ToolCallResult", + }, +) + + +class ToolCall(proto.Message): + r"""Represents a call of a specific tool's action with the + specified inputs. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + tool (str): + Optional. The [tool][google.cloud.dialogflow.v2beta1.Tool] + associated with this call. Format: + ``projects//locations//tools/``. + + This field is a member of `oneof`_ ``source``. + tool_display_name (str): + Optional. A human readable short name of the + tool, to be shown on the UI. + tool_display_details (str): + Optional. A human readable description of the + tool. + action (str): + Optional. The name of the tool's action + associated with this call. + input_parameters (google.protobuf.struct_pb2.Struct): + Optional. The action's input parameters. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Create time of the tool call. + answer_record (str): + Optional. The answer record associated with + this tool call. + state (google.cloud.dialogflow_v2beta1.types.ToolCall.State): + Output only. State of the tool call + """ + + class State(proto.Enum): + r"""Tool call states. + + Values: + STATE_UNSPECIFIED (0): + Default value. + TRIGGERED (1): + The tool call has been triggered. + NEEDS_CONFIRMATION (2): + The tool call requires confirmation from a + human. + """ + STATE_UNSPECIFIED = 0 + TRIGGERED = 1 + NEEDS_CONFIRMATION = 2 + + tool: str = proto.Field( + proto.STRING, + number=1, + oneof="source", + ) + tool_display_name: str = proto.Field( + proto.STRING, + number=9, + ) + tool_display_details: str = proto.Field( + proto.STRING, + number=10, + ) + action: str = proto.Field( + proto.STRING, + number=2, + ) + input_parameters: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=3, + message=struct_pb2.Struct, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + answer_record: str = proto.Field( + proto.STRING, + number=6, + ) + state: State = proto.Field( + proto.ENUM, + number=7, + enum=State, + ) + + +class ToolCallResult(proto.Message): + r"""The result of calling a tool's action. + + 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: + tool (str): + Optional. The [tool][google.cloud.dialogflow.v2beta1.Tool] + associated with this call. Format: + ``projects//locations//tools/``. + + This field is a member of `oneof`_ ``source``. + action (str): + Optional. The name of the tool's action + associated with this call. + error (google.cloud.dialogflow_v2beta1.types.ToolCallResult.Error): + The tool call's error. + + This field is a member of `oneof`_ ``result``. + raw_content (bytes): + Only populated if the response content is not + utf-8 encoded. (by definition byte fields are + base64 encoded). + + This field is a member of `oneof`_ ``result``. + content (str): + Only populated if the response content is + utf-8 encoded. + + This field is a member of `oneof`_ ``result``. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Create time of the tool call + result. + answer_record (str): + Optional. The answer record associated with + this tool call result. + """ + + class Error(proto.Message): + r"""An error produced by the tool call. + + Attributes: + message (str): + Optional. The error message of the function. + """ + + message: str = proto.Field( + proto.STRING, + number=1, + ) + + tool: str = proto.Field( + proto.STRING, + number=1, + oneof="source", + ) + action: str = proto.Field( + proto.STRING, + number=2, + ) + error: Error = proto.Field( + proto.MESSAGE, + number=3, + oneof="result", + message=Error, + ) + raw_content: bytes = proto.Field( + proto.BYTES, + number=5, + oneof="result", + ) + content: str = proto.Field( + proto.STRING, + number=6, + oneof="result", + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=7, + message=timestamp_pb2.Timestamp, + ) + answer_record: str = proto.Field( + proto.STRING, + number=9, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-dialogflow/noxfile.py b/packages/google-cloud-dialogflow/noxfile.py index f2804e68c641..c4844130aa13 100644 --- a/packages/google-cloud-dialogflow/noxfile.py +++ b/packages/google-cloud-dialogflow/noxfile.py @@ -27,6 +27,10 @@ LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] +# Add samples to the list of directories to format if the directory exists. +if os.path.isdir("samples"): + LINT_PATHS.append("samples") + ALL_PYTHON = [ "3.7", "3.8", diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_export_agent_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_export_agent_async.py index 5d375e6e1d7a..e88262d0ad26 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_export_agent_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_export_agent_async.py @@ -54,4 +54,5 @@ async def sample_export_agent(): # Handle the response print(response) + # [END dialogflow_v2_generated_Agents_ExportAgent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_export_agent_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_export_agent_sync.py index a618e7d4477b..4478a51600fe 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_export_agent_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_export_agent_sync.py @@ -54,4 +54,5 @@ def sample_export_agent(): # Handle the response print(response) + # [END dialogflow_v2_generated_Agents_ExportAgent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_get_agent_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_get_agent_async.py index 8156446a376a..67c85dd0570e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_get_agent_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_get_agent_async.py @@ -49,4 +49,5 @@ async def sample_get_agent(): # Handle the response print(response) + # [END dialogflow_v2_generated_Agents_GetAgent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_get_agent_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_get_agent_sync.py index ecb9eeea42d1..04446d5a9967 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_get_agent_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_get_agent_sync.py @@ -49,4 +49,5 @@ def sample_get_agent(): # Handle the response print(response) + # [END dialogflow_v2_generated_Agents_GetAgent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_get_validation_result_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_get_validation_result_async.py index 30ed950be679..8213cd4ed660 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_get_validation_result_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_get_validation_result_async.py @@ -49,4 +49,5 @@ async def sample_get_validation_result(): # Handle the response print(response) + # [END dialogflow_v2_generated_Agents_GetValidationResult_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_get_validation_result_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_get_validation_result_sync.py index 09dcba6b2e74..457969c85297 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_get_validation_result_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_get_validation_result_sync.py @@ -49,4 +49,5 @@ def sample_get_validation_result(): # Handle the response print(response) + # [END dialogflow_v2_generated_Agents_GetValidationResult_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_import_agent_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_import_agent_async.py index aa0fd500683e..836d87c9d9a7 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_import_agent_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_import_agent_async.py @@ -54,4 +54,5 @@ async def sample_import_agent(): # Handle the response print(response) + # [END dialogflow_v2_generated_Agents_ImportAgent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_import_agent_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_import_agent_sync.py index 43e20c305eed..092b50fb54da 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_import_agent_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_import_agent_sync.py @@ -54,4 +54,5 @@ def sample_import_agent(): # Handle the response print(response) + # [END dialogflow_v2_generated_Agents_ImportAgent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_restore_agent_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_restore_agent_async.py index 00fdc500064f..b7e044163c82 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_restore_agent_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_restore_agent_async.py @@ -54,4 +54,5 @@ async def sample_restore_agent(): # Handle the response print(response) + # [END dialogflow_v2_generated_Agents_RestoreAgent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_restore_agent_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_restore_agent_sync.py index 8853f7114812..4f8f5ce33216 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_restore_agent_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_restore_agent_sync.py @@ -54,4 +54,5 @@ def sample_restore_agent(): # Handle the response print(response) + # [END dialogflow_v2_generated_Agents_RestoreAgent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_search_agents_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_search_agents_async.py index 849daea42048..81c7182b3952 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_search_agents_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_search_agents_async.py @@ -50,4 +50,5 @@ async def sample_search_agents(): async for response in page_result: print(response) + # [END dialogflow_v2_generated_Agents_SearchAgents_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_search_agents_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_search_agents_sync.py index 65e27ed4bee2..f7005c100dcb 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_search_agents_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_search_agents_sync.py @@ -50,4 +50,5 @@ def sample_search_agents(): for response in page_result: print(response) + # [END dialogflow_v2_generated_Agents_SearchAgents_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_set_agent_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_set_agent_async.py index a38ae1bf86a2..f71a082e0942 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_set_agent_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_set_agent_async.py @@ -55,4 +55,5 @@ async def sample_set_agent(): # Handle the response print(response) + # [END dialogflow_v2_generated_Agents_SetAgent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_set_agent_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_set_agent_sync.py index ca370ef3abca..83a23314f884 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_set_agent_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_set_agent_sync.py @@ -55,4 +55,5 @@ def sample_set_agent(): # Handle the response print(response) + # [END dialogflow_v2_generated_Agents_SetAgent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_train_agent_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_train_agent_async.py index 075594ea97c7..03a0fae3673d 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_train_agent_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_train_agent_async.py @@ -53,4 +53,5 @@ async def sample_train_agent(): # Handle the response print(response) + # [END dialogflow_v2_generated_Agents_TrainAgent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_train_agent_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_train_agent_sync.py index 96f428250227..a0bd8226dc4c 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_train_agent_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_agents_train_agent_sync.py @@ -53,4 +53,5 @@ def sample_train_agent(): # Handle the response print(response) + # [END dialogflow_v2_generated_Agents_TrainAgent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_answer_records_list_answer_records_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_answer_records_list_answer_records_async.py index 0a2bb42dfab9..d70a88c60c1e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_answer_records_list_answer_records_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_answer_records_list_answer_records_async.py @@ -50,4 +50,5 @@ async def sample_list_answer_records(): async for response in page_result: print(response) + # [END dialogflow_v2_generated_AnswerRecords_ListAnswerRecords_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_answer_records_list_answer_records_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_answer_records_list_answer_records_sync.py index dee9d660fa8d..04f84892313c 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_answer_records_list_answer_records_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_answer_records_list_answer_records_sync.py @@ -50,4 +50,5 @@ def sample_list_answer_records(): for response in page_result: print(response) + # [END dialogflow_v2_generated_AnswerRecords_ListAnswerRecords_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_answer_records_update_answer_record_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_answer_records_update_answer_record_async.py index 3827b1554209..f5d7bfbc5029 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_answer_records_update_answer_record_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_answer_records_update_answer_record_async.py @@ -39,8 +39,7 @@ async def sample_update_answer_record(): client = dialogflow_v2.AnswerRecordsAsyncClient() # Initialize request argument(s) - request = dialogflow_v2.UpdateAnswerRecordRequest( - ) + request = dialogflow_v2.UpdateAnswerRecordRequest() # Make the request response = await client.update_answer_record(request=request) @@ -48,4 +47,5 @@ async def sample_update_answer_record(): # Handle the response print(response) + # [END dialogflow_v2_generated_AnswerRecords_UpdateAnswerRecord_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_answer_records_update_answer_record_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_answer_records_update_answer_record_sync.py index ec519e47f039..6d439c114bd9 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_answer_records_update_answer_record_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_answer_records_update_answer_record_sync.py @@ -39,8 +39,7 @@ def sample_update_answer_record(): client = dialogflow_v2.AnswerRecordsClient() # Initialize request argument(s) - request = dialogflow_v2.UpdateAnswerRecordRequest( - ) + request = dialogflow_v2.UpdateAnswerRecordRequest() # Make the request response = client.update_answer_record(request=request) @@ -48,4 +47,5 @@ def sample_update_answer_record(): # Handle the response print(response) + # [END dialogflow_v2_generated_AnswerRecords_UpdateAnswerRecord_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_create_context_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_create_context_async.py index 62dd3aba0dd7..1443fc8420ab 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_create_context_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_create_context_async.py @@ -53,4 +53,5 @@ async def sample_create_context(): # Handle the response print(response) + # [END dialogflow_v2_generated_Contexts_CreateContext_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_create_context_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_create_context_sync.py index 29fdc7f12676..9701ed4fab6a 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_create_context_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_create_context_sync.py @@ -53,4 +53,5 @@ def sample_create_context(): # Handle the response print(response) + # [END dialogflow_v2_generated_Contexts_CreateContext_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_get_context_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_get_context_async.py index a206b433f562..f445457b3e08 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_get_context_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_get_context_async.py @@ -49,4 +49,5 @@ async def sample_get_context(): # Handle the response print(response) + # [END dialogflow_v2_generated_Contexts_GetContext_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_get_context_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_get_context_sync.py index 839aff5f7b55..60fc31107935 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_get_context_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_get_context_sync.py @@ -49,4 +49,5 @@ def sample_get_context(): # Handle the response print(response) + # [END dialogflow_v2_generated_Contexts_GetContext_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_list_contexts_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_list_contexts_async.py index 9740198d4742..46c47ad0c85f 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_list_contexts_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_list_contexts_async.py @@ -50,4 +50,5 @@ async def sample_list_contexts(): async for response in page_result: print(response) + # [END dialogflow_v2_generated_Contexts_ListContexts_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_list_contexts_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_list_contexts_sync.py index 0a4ee039c34f..be36cc0325ac 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_list_contexts_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_list_contexts_sync.py @@ -50,4 +50,5 @@ def sample_list_contexts(): for response in page_result: print(response) + # [END dialogflow_v2_generated_Contexts_ListContexts_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_update_context_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_update_context_async.py index a6ccd6848832..edab2ec5a275 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_update_context_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_update_context_async.py @@ -52,4 +52,5 @@ async def sample_update_context(): # Handle the response print(response) + # [END dialogflow_v2_generated_Contexts_UpdateContext_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_update_context_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_update_context_sync.py index 41c7c65d0e9b..6807e6152f78 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_update_context_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_contexts_update_context_sync.py @@ -52,4 +52,5 @@ def sample_update_context(): # Handle the response print(response) + # [END dialogflow_v2_generated_Contexts_UpdateContext_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_create_conversation_dataset_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_create_conversation_dataset_async.py index 701df28ef6ca..5fc905f60d57 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_create_conversation_dataset_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_create_conversation_dataset_async.py @@ -57,4 +57,5 @@ async def sample_create_conversation_dataset(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationDatasets_CreateConversationDataset_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_create_conversation_dataset_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_create_conversation_dataset_sync.py index c98d548030a6..bec2880c0cdb 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_create_conversation_dataset_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_create_conversation_dataset_sync.py @@ -57,4 +57,5 @@ def sample_create_conversation_dataset(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationDatasets_CreateConversationDataset_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_delete_conversation_dataset_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_delete_conversation_dataset_async.py index 5559e4d20730..fbee2588b18d 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_delete_conversation_dataset_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_delete_conversation_dataset_async.py @@ -53,4 +53,5 @@ async def sample_delete_conversation_dataset(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationDatasets_DeleteConversationDataset_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_delete_conversation_dataset_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_delete_conversation_dataset_sync.py index 22e9e763b146..69fd9e1d68bb 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_delete_conversation_dataset_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_delete_conversation_dataset_sync.py @@ -53,4 +53,5 @@ def sample_delete_conversation_dataset(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationDatasets_DeleteConversationDataset_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_get_conversation_dataset_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_get_conversation_dataset_async.py index 312903d24041..b0e77db8d471 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_get_conversation_dataset_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_get_conversation_dataset_async.py @@ -49,4 +49,5 @@ async def sample_get_conversation_dataset(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationDatasets_GetConversationDataset_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_get_conversation_dataset_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_get_conversation_dataset_sync.py index fbdcac8a7751..6f6fcc439112 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_get_conversation_dataset_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_get_conversation_dataset_sync.py @@ -49,4 +49,5 @@ def sample_get_conversation_dataset(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationDatasets_GetConversationDataset_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_import_conversation_data_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_import_conversation_data_async.py index 0faa32421429..b93f6bb90960 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_import_conversation_data_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_import_conversation_data_async.py @@ -40,7 +40,7 @@ async def sample_import_conversation_data(): # Initialize request argument(s) input_config = dialogflow_v2.InputConfig() - input_config.gcs_source.uris = ['uris_value1', 'uris_value2'] + input_config.gcs_source.uris = ["uris_value1", "uris_value2"] request = dialogflow_v2.ImportConversationDataRequest( name="name_value", @@ -57,4 +57,5 @@ async def sample_import_conversation_data(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationDatasets_ImportConversationData_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_import_conversation_data_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_import_conversation_data_sync.py index c49140b5268d..6b937a217831 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_import_conversation_data_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_import_conversation_data_sync.py @@ -40,7 +40,7 @@ def sample_import_conversation_data(): # Initialize request argument(s) input_config = dialogflow_v2.InputConfig() - input_config.gcs_source.uris = ['uris_value1', 'uris_value2'] + input_config.gcs_source.uris = ["uris_value1", "uris_value2"] request = dialogflow_v2.ImportConversationDataRequest( name="name_value", @@ -57,4 +57,5 @@ def sample_import_conversation_data(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationDatasets_ImportConversationData_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_list_conversation_datasets_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_list_conversation_datasets_async.py index 5ff13c3121b8..58657e2424c8 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_list_conversation_datasets_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_list_conversation_datasets_async.py @@ -50,4 +50,5 @@ async def sample_list_conversation_datasets(): async for response in page_result: print(response) + # [END dialogflow_v2_generated_ConversationDatasets_ListConversationDatasets_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_list_conversation_datasets_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_list_conversation_datasets_sync.py index cfb72d4a4186..c5f98d051b0f 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_list_conversation_datasets_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_datasets_list_conversation_datasets_sync.py @@ -50,4 +50,5 @@ def sample_list_conversation_datasets(): for response in page_result: print(response) + # [END dialogflow_v2_generated_ConversationDatasets_ListConversationDatasets_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_create_conversation_model_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_create_conversation_model_async.py index 872f54f9fe91..d79dfa0a3b31 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_create_conversation_model_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_create_conversation_model_async.py @@ -57,4 +57,5 @@ async def sample_create_conversation_model(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationModels_CreateConversationModel_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_create_conversation_model_evaluation_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_create_conversation_model_evaluation_async.py index a2f05abe30da..7b236620356d 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_create_conversation_model_evaluation_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_create_conversation_model_evaluation_async.py @@ -53,4 +53,5 @@ async def sample_create_conversation_model_evaluation(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationModels_CreateConversationModelEvaluation_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_create_conversation_model_evaluation_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_create_conversation_model_evaluation_sync.py index de1bce94c98d..d4a0660551ea 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_create_conversation_model_evaluation_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_create_conversation_model_evaluation_sync.py @@ -53,4 +53,5 @@ def sample_create_conversation_model_evaluation(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationModels_CreateConversationModelEvaluation_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_create_conversation_model_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_create_conversation_model_sync.py index 22c44e00c1cd..84e9faf22a55 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_create_conversation_model_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_create_conversation_model_sync.py @@ -57,4 +57,5 @@ def sample_create_conversation_model(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationModels_CreateConversationModel_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_delete_conversation_model_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_delete_conversation_model_async.py index 47f31daed845..220c249112ae 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_delete_conversation_model_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_delete_conversation_model_async.py @@ -53,4 +53,5 @@ async def sample_delete_conversation_model(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationModels_DeleteConversationModel_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_delete_conversation_model_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_delete_conversation_model_sync.py index 4cb4f8b89fa9..940fb7df9bac 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_delete_conversation_model_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_delete_conversation_model_sync.py @@ -53,4 +53,5 @@ def sample_delete_conversation_model(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationModels_DeleteConversationModel_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_deploy_conversation_model_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_deploy_conversation_model_async.py index e9d10fb36674..19131c6ae326 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_deploy_conversation_model_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_deploy_conversation_model_async.py @@ -53,4 +53,5 @@ async def sample_deploy_conversation_model(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationModels_DeployConversationModel_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_deploy_conversation_model_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_deploy_conversation_model_sync.py index 22406a046c50..7d8b0267447f 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_deploy_conversation_model_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_deploy_conversation_model_sync.py @@ -53,4 +53,5 @@ def sample_deploy_conversation_model(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationModels_DeployConversationModel_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_get_conversation_model_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_get_conversation_model_async.py index 53a3bf634952..d5acab7f2d06 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_get_conversation_model_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_get_conversation_model_async.py @@ -49,4 +49,5 @@ async def sample_get_conversation_model(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationModels_GetConversationModel_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_get_conversation_model_evaluation_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_get_conversation_model_evaluation_async.py index 25eeebd97831..2eb9550deb3c 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_get_conversation_model_evaluation_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_get_conversation_model_evaluation_async.py @@ -49,4 +49,5 @@ async def sample_get_conversation_model_evaluation(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationModels_GetConversationModelEvaluation_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_get_conversation_model_evaluation_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_get_conversation_model_evaluation_sync.py index 47e728a8bd5d..f27091fd888e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_get_conversation_model_evaluation_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_get_conversation_model_evaluation_sync.py @@ -49,4 +49,5 @@ def sample_get_conversation_model_evaluation(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationModels_GetConversationModelEvaluation_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_get_conversation_model_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_get_conversation_model_sync.py index ebec471376f7..9d177641a89d 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_get_conversation_model_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_get_conversation_model_sync.py @@ -49,4 +49,5 @@ def sample_get_conversation_model(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationModels_GetConversationModel_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_list_conversation_model_evaluations_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_list_conversation_model_evaluations_async.py index 5dd7e35f2abe..f181d5e0ffe5 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_list_conversation_model_evaluations_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_list_conversation_model_evaluations_async.py @@ -50,4 +50,5 @@ async def sample_list_conversation_model_evaluations(): async for response in page_result: print(response) + # [END dialogflow_v2_generated_ConversationModels_ListConversationModelEvaluations_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_list_conversation_model_evaluations_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_list_conversation_model_evaluations_sync.py index de75ba167509..eb11a4202586 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_list_conversation_model_evaluations_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_list_conversation_model_evaluations_sync.py @@ -50,4 +50,5 @@ def sample_list_conversation_model_evaluations(): for response in page_result: print(response) + # [END dialogflow_v2_generated_ConversationModels_ListConversationModelEvaluations_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_list_conversation_models_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_list_conversation_models_async.py index dade8b3c6af1..0a4e5e325a92 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_list_conversation_models_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_list_conversation_models_async.py @@ -50,4 +50,5 @@ async def sample_list_conversation_models(): async for response in page_result: print(response) + # [END dialogflow_v2_generated_ConversationModels_ListConversationModels_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_list_conversation_models_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_list_conversation_models_sync.py index 83c7978429bc..fad35a118db5 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_list_conversation_models_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_list_conversation_models_sync.py @@ -50,4 +50,5 @@ def sample_list_conversation_models(): for response in page_result: print(response) + # [END dialogflow_v2_generated_ConversationModels_ListConversationModels_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_undeploy_conversation_model_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_undeploy_conversation_model_async.py index f6a1bfdbdba4..38dbc67e8750 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_undeploy_conversation_model_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_undeploy_conversation_model_async.py @@ -53,4 +53,5 @@ async def sample_undeploy_conversation_model(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationModels_UndeployConversationModel_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_undeploy_conversation_model_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_undeploy_conversation_model_sync.py index cd2eb2050c4b..c3ed2dc5fcd0 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_undeploy_conversation_model_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_models_undeploy_conversation_model_sync.py @@ -53,4 +53,5 @@ def sample_undeploy_conversation_model(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationModels_UndeployConversationModel_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_clear_suggestion_feature_config_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_clear_suggestion_feature_config_async.py index 1e72c4a06e98..de61ff4429e2 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_clear_suggestion_feature_config_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_clear_suggestion_feature_config_async.py @@ -55,4 +55,5 @@ async def sample_clear_suggestion_feature_config(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationProfiles_ClearSuggestionFeatureConfig_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_clear_suggestion_feature_config_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_clear_suggestion_feature_config_sync.py index 793eaf49e525..fd8f753fe42c 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_clear_suggestion_feature_config_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_clear_suggestion_feature_config_sync.py @@ -55,4 +55,5 @@ def sample_clear_suggestion_feature_config(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationProfiles_ClearSuggestionFeatureConfig_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_create_conversation_profile_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_create_conversation_profile_async.py index fff32ed7d71d..b026a4840167 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_create_conversation_profile_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_create_conversation_profile_async.py @@ -53,4 +53,5 @@ async def sample_create_conversation_profile(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationProfiles_CreateConversationProfile_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_create_conversation_profile_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_create_conversation_profile_sync.py index fa191d6454b1..6d1945349d66 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_create_conversation_profile_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_create_conversation_profile_sync.py @@ -53,4 +53,5 @@ def sample_create_conversation_profile(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationProfiles_CreateConversationProfile_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_get_conversation_profile_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_get_conversation_profile_async.py index 67231e846888..d5235f58b97e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_get_conversation_profile_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_get_conversation_profile_async.py @@ -49,4 +49,5 @@ async def sample_get_conversation_profile(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationProfiles_GetConversationProfile_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_get_conversation_profile_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_get_conversation_profile_sync.py index a41faa8aba41..c392a7fe3100 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_get_conversation_profile_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_get_conversation_profile_sync.py @@ -49,4 +49,5 @@ def sample_get_conversation_profile(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationProfiles_GetConversationProfile_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_list_conversation_profiles_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_list_conversation_profiles_async.py index 9595bde9c476..83ab76eaa8a0 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_list_conversation_profiles_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_list_conversation_profiles_async.py @@ -50,4 +50,5 @@ async def sample_list_conversation_profiles(): async for response in page_result: print(response) + # [END dialogflow_v2_generated_ConversationProfiles_ListConversationProfiles_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_list_conversation_profiles_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_list_conversation_profiles_sync.py index 2f3edaf256e5..4db705511fac 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_list_conversation_profiles_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_list_conversation_profiles_sync.py @@ -50,4 +50,5 @@ def sample_list_conversation_profiles(): for response in page_result: print(response) + # [END dialogflow_v2_generated_ConversationProfiles_ListConversationProfiles_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_set_suggestion_feature_config_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_set_suggestion_feature_config_async.py index 2ad29e56b84c..db73189da610 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_set_suggestion_feature_config_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_set_suggestion_feature_config_async.py @@ -54,4 +54,5 @@ async def sample_set_suggestion_feature_config(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationProfiles_SetSuggestionFeatureConfig_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_set_suggestion_feature_config_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_set_suggestion_feature_config_sync.py index 9584bf64e753..7ea8fbe3d153 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_set_suggestion_feature_config_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_set_suggestion_feature_config_sync.py @@ -54,4 +54,5 @@ def sample_set_suggestion_feature_config(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationProfiles_SetSuggestionFeatureConfig_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_update_conversation_profile_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_update_conversation_profile_async.py index b41b420e7796..ad2b10bba098 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_update_conversation_profile_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_update_conversation_profile_async.py @@ -52,4 +52,5 @@ async def sample_update_conversation_profile(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationProfiles_UpdateConversationProfile_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_update_conversation_profile_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_update_conversation_profile_sync.py index 286070228d8a..d81332fa1eb3 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_update_conversation_profile_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversation_profiles_update_conversation_profile_sync.py @@ -52,4 +52,5 @@ def sample_update_conversation_profile(): # Handle the response print(response) + # [END dialogflow_v2_generated_ConversationProfiles_UpdateConversationProfile_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_complete_conversation_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_complete_conversation_async.py index 50004cda52c8..d27dffbcd83f 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_complete_conversation_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_complete_conversation_async.py @@ -49,4 +49,5 @@ async def sample_complete_conversation(): # Handle the response print(response) + # [END dialogflow_v2_generated_Conversations_CompleteConversation_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_complete_conversation_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_complete_conversation_sync.py index 4692a80d3363..ed8620296dcd 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_complete_conversation_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_complete_conversation_sync.py @@ -49,4 +49,5 @@ def sample_complete_conversation(): # Handle the response print(response) + # [END dialogflow_v2_generated_Conversations_CompleteConversation_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_create_conversation_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_create_conversation_async.py index d495075008a5..7bd7d844f402 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_create_conversation_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_create_conversation_async.py @@ -53,4 +53,5 @@ async def sample_create_conversation(): # Handle the response print(response) + # [END dialogflow_v2_generated_Conversations_CreateConversation_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_create_conversation_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_create_conversation_sync.py index 7821f6d779d8..17472a768676 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_create_conversation_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_create_conversation_sync.py @@ -53,4 +53,5 @@ def sample_create_conversation(): # Handle the response print(response) + # [END dialogflow_v2_generated_Conversations_CreateConversation_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_stateless_suggestion_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_stateless_suggestion_async.py index 493170245151..8f82ba4601ee 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_stateless_suggestion_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_stateless_suggestion_async.py @@ -53,4 +53,5 @@ async def sample_generate_stateless_suggestion(): # Handle the response print(response) + # [END dialogflow_v2_generated_Conversations_GenerateStatelessSuggestion_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_stateless_suggestion_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_stateless_suggestion_sync.py index 816d127a6fc9..e9a375dfb7cf 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_stateless_suggestion_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_stateless_suggestion_sync.py @@ -53,4 +53,5 @@ def sample_generate_stateless_suggestion(): # Handle the response print(response) + # [END dialogflow_v2_generated_Conversations_GenerateStatelessSuggestion_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_stateless_summary_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_stateless_summary_async.py index 2d8d1bb8caa7..5222383f0588 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_stateless_summary_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_stateless_summary_async.py @@ -57,4 +57,5 @@ async def sample_generate_stateless_summary(): # Handle the response print(response) + # [END dialogflow_v2_generated_Conversations_GenerateStatelessSummary_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_stateless_summary_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_stateless_summary_sync.py index a62df88d7b6b..87a259251adf 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_stateless_summary_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_stateless_summary_sync.py @@ -57,4 +57,5 @@ def sample_generate_stateless_summary(): # Handle the response print(response) + # [END dialogflow_v2_generated_Conversations_GenerateStatelessSummary_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_suggestions_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_suggestions_async.py index 742053a69b0d..53536134602e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_suggestions_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_suggestions_async.py @@ -49,4 +49,5 @@ async def sample_generate_suggestions(): # Handle the response print(response) + # [END dialogflow_v2_generated_Conversations_GenerateSuggestions_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_suggestions_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_suggestions_sync.py index 236acb706204..0f6135005914 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_suggestions_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_generate_suggestions_sync.py @@ -49,4 +49,5 @@ def sample_generate_suggestions(): # Handle the response print(response) + # [END dialogflow_v2_generated_Conversations_GenerateSuggestions_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_get_conversation_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_get_conversation_async.py index 80c1bdbe1624..f6f951efd5d9 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_get_conversation_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_get_conversation_async.py @@ -49,4 +49,5 @@ async def sample_get_conversation(): # Handle the response print(response) + # [END dialogflow_v2_generated_Conversations_GetConversation_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_get_conversation_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_get_conversation_sync.py index befb20ecff8f..2e8fe4f6529d 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_get_conversation_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_get_conversation_sync.py @@ -49,4 +49,5 @@ def sample_get_conversation(): # Handle the response print(response) + # [END dialogflow_v2_generated_Conversations_GetConversation_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_ingest_context_references_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_ingest_context_references_async.py index 143c9043550b..fe1c60a83efa 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_ingest_context_references_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_ingest_context_references_async.py @@ -49,4 +49,5 @@ async def sample_ingest_context_references(): # Handle the response print(response) + # [END dialogflow_v2_generated_Conversations_IngestContextReferences_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_ingest_context_references_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_ingest_context_references_sync.py index 6884f31c7867..ffc89b350a74 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_ingest_context_references_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_ingest_context_references_sync.py @@ -49,4 +49,5 @@ def sample_ingest_context_references(): # Handle the response print(response) + # [END dialogflow_v2_generated_Conversations_IngestContextReferences_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_list_conversations_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_list_conversations_async.py index 05c4217acfa4..074226197e1c 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_list_conversations_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_list_conversations_async.py @@ -50,4 +50,5 @@ async def sample_list_conversations(): async for response in page_result: print(response) + # [END dialogflow_v2_generated_Conversations_ListConversations_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_list_conversations_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_list_conversations_sync.py index 03aea1f32148..e29e98aff228 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_list_conversations_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_list_conversations_sync.py @@ -50,4 +50,5 @@ def sample_list_conversations(): for response in page_result: print(response) + # [END dialogflow_v2_generated_Conversations_ListConversations_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_list_messages_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_list_messages_async.py index 3df9a4ebdb53..322ca5af2732 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_list_messages_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_list_messages_async.py @@ -50,4 +50,5 @@ async def sample_list_messages(): async for response in page_result: print(response) + # [END dialogflow_v2_generated_Conversations_ListMessages_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_list_messages_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_list_messages_sync.py index 2386d0d7088d..df2369367b24 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_list_messages_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_list_messages_sync.py @@ -50,4 +50,5 @@ def sample_list_messages(): for response in page_result: print(response) + # [END dialogflow_v2_generated_Conversations_ListMessages_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_search_knowledge_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_search_knowledge_async.py index 7d820bc742ea..de7a19abef51 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_search_knowledge_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_search_knowledge_async.py @@ -56,4 +56,5 @@ async def sample_search_knowledge(): # Handle the response print(response) + # [END dialogflow_v2_generated_Conversations_SearchKnowledge_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_search_knowledge_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_search_knowledge_sync.py index 2095c1d47c75..341bda6c8e58 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_search_knowledge_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_search_knowledge_sync.py @@ -56,4 +56,5 @@ def sample_search_knowledge(): # Handle the response print(response) + # [END dialogflow_v2_generated_Conversations_SearchKnowledge_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_suggest_conversation_summary_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_suggest_conversation_summary_async.py index c2f8bb0b43ec..90882f531cf1 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_suggest_conversation_summary_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_suggest_conversation_summary_async.py @@ -49,4 +49,5 @@ async def sample_suggest_conversation_summary(): # Handle the response print(response) + # [END dialogflow_v2_generated_Conversations_SuggestConversationSummary_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_suggest_conversation_summary_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_suggest_conversation_summary_sync.py index cd2ccd30e0da..8675824e95d4 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_suggest_conversation_summary_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_conversations_suggest_conversation_summary_sync.py @@ -49,4 +49,5 @@ def sample_suggest_conversation_summary(): # Handle the response print(response) + # [END dialogflow_v2_generated_Conversations_SuggestConversationSummary_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_create_document_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_create_document_async.py index 1e1d758d1784..53d0caf16076 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_create_document_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_create_document_async.py @@ -43,7 +43,7 @@ async def sample_create_document(): document.content_uri = "content_uri_value" document.display_name = "display_name_value" document.mime_type = "mime_type_value" - document.knowledge_types = ['AGENT_FACING_SMART_REPLY'] + document.knowledge_types = ["AGENT_FACING_SMART_REPLY"] request = dialogflow_v2.CreateDocumentRequest( parent="parent_value", @@ -60,4 +60,5 @@ async def sample_create_document(): # Handle the response print(response) + # [END dialogflow_v2_generated_Documents_CreateDocument_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_create_document_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_create_document_sync.py index 7c010f28848f..144b4718637e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_create_document_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_create_document_sync.py @@ -43,7 +43,7 @@ def sample_create_document(): document.content_uri = "content_uri_value" document.display_name = "display_name_value" document.mime_type = "mime_type_value" - document.knowledge_types = ['AGENT_FACING_SMART_REPLY'] + document.knowledge_types = ["AGENT_FACING_SMART_REPLY"] request = dialogflow_v2.CreateDocumentRequest( parent="parent_value", @@ -60,4 +60,5 @@ def sample_create_document(): # Handle the response print(response) + # [END dialogflow_v2_generated_Documents_CreateDocument_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_delete_document_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_delete_document_async.py index 48ca4f5ee293..9046ed0cd1ca 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_delete_document_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_delete_document_async.py @@ -53,4 +53,5 @@ async def sample_delete_document(): # Handle the response print(response) + # [END dialogflow_v2_generated_Documents_DeleteDocument_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_delete_document_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_delete_document_sync.py index 2012caf7ae7c..9ea894b8db27 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_delete_document_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_delete_document_sync.py @@ -53,4 +53,5 @@ def sample_delete_document(): # Handle the response print(response) + # [END dialogflow_v2_generated_Documents_DeleteDocument_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_export_document_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_export_document_async.py index 70c7b9bba7af..552a650db777 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_export_document_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_export_document_async.py @@ -53,4 +53,5 @@ async def sample_export_document(): # Handle the response print(response) + # [END dialogflow_v2_generated_Documents_ExportDocument_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_export_document_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_export_document_sync.py index eb36b0df381f..7fd9137e242e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_export_document_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_export_document_sync.py @@ -53,4 +53,5 @@ def sample_export_document(): # Handle the response print(response) + # [END dialogflow_v2_generated_Documents_ExportDocument_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_get_document_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_get_document_async.py index 1751a2a576dc..457453fd3abd 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_get_document_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_get_document_async.py @@ -49,4 +49,5 @@ async def sample_get_document(): # Handle the response print(response) + # [END dialogflow_v2_generated_Documents_GetDocument_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_get_document_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_get_document_sync.py index 71279976a5fc..8e7fed9e1c80 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_get_document_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_get_document_sync.py @@ -49,4 +49,5 @@ def sample_get_document(): # Handle the response print(response) + # [END dialogflow_v2_generated_Documents_GetDocument_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_import_documents_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_import_documents_async.py index ceab6126db6c..dc7044ca1efc 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_import_documents_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_import_documents_async.py @@ -40,11 +40,11 @@ async def sample_import_documents(): # Initialize request argument(s) gcs_source = dialogflow_v2.GcsSources() - gcs_source.uris = ['uris_value1', 'uris_value2'] + gcs_source.uris = ["uris_value1", "uris_value2"] document_template = dialogflow_v2.ImportDocumentTemplate() document_template.mime_type = "mime_type_value" - document_template.knowledge_types = ['AGENT_FACING_SMART_REPLY'] + document_template.knowledge_types = ["AGENT_FACING_SMART_REPLY"] request = dialogflow_v2.ImportDocumentsRequest( gcs_source=gcs_source, @@ -62,4 +62,5 @@ async def sample_import_documents(): # Handle the response print(response) + # [END dialogflow_v2_generated_Documents_ImportDocuments_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_import_documents_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_import_documents_sync.py index a4feb2d02ef1..f35e965d8d50 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_import_documents_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_import_documents_sync.py @@ -40,11 +40,11 @@ def sample_import_documents(): # Initialize request argument(s) gcs_source = dialogflow_v2.GcsSources() - gcs_source.uris = ['uris_value1', 'uris_value2'] + gcs_source.uris = ["uris_value1", "uris_value2"] document_template = dialogflow_v2.ImportDocumentTemplate() document_template.mime_type = "mime_type_value" - document_template.knowledge_types = ['AGENT_FACING_SMART_REPLY'] + document_template.knowledge_types = ["AGENT_FACING_SMART_REPLY"] request = dialogflow_v2.ImportDocumentsRequest( gcs_source=gcs_source, @@ -62,4 +62,5 @@ def sample_import_documents(): # Handle the response print(response) + # [END dialogflow_v2_generated_Documents_ImportDocuments_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_list_documents_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_list_documents_async.py index 07d4ce0b0682..7f318b7f52f2 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_list_documents_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_list_documents_async.py @@ -50,4 +50,5 @@ async def sample_list_documents(): async for response in page_result: print(response) + # [END dialogflow_v2_generated_Documents_ListDocuments_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_list_documents_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_list_documents_sync.py index 3d004a396ecf..e2c05021ad86 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_list_documents_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_list_documents_sync.py @@ -50,4 +50,5 @@ def sample_list_documents(): for response in page_result: print(response) + # [END dialogflow_v2_generated_Documents_ListDocuments_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_reload_document_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_reload_document_async.py index be4577df8596..6efa406dd67e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_reload_document_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_reload_document_async.py @@ -54,4 +54,5 @@ async def sample_reload_document(): # Handle the response print(response) + # [END dialogflow_v2_generated_Documents_ReloadDocument_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_reload_document_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_reload_document_sync.py index 85c3543ea18c..c4c4a4fd129e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_reload_document_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_reload_document_sync.py @@ -54,4 +54,5 @@ def sample_reload_document(): # Handle the response print(response) + # [END dialogflow_v2_generated_Documents_ReloadDocument_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_update_document_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_update_document_async.py index c9da36a6e809..a93ed3b51def 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_update_document_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_update_document_async.py @@ -43,7 +43,7 @@ async def sample_update_document(): document.content_uri = "content_uri_value" document.display_name = "display_name_value" document.mime_type = "mime_type_value" - document.knowledge_types = ['AGENT_FACING_SMART_REPLY'] + document.knowledge_types = ["AGENT_FACING_SMART_REPLY"] request = dialogflow_v2.UpdateDocumentRequest( document=document, @@ -59,4 +59,5 @@ async def sample_update_document(): # Handle the response print(response) + # [END dialogflow_v2_generated_Documents_UpdateDocument_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_update_document_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_update_document_sync.py index e316de09e3be..696b350913a6 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_update_document_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_documents_update_document_sync.py @@ -43,7 +43,7 @@ def sample_update_document(): document.content_uri = "content_uri_value" document.display_name = "display_name_value" document.mime_type = "mime_type_value" - document.knowledge_types = ['AGENT_FACING_SMART_REPLY'] + document.knowledge_types = ["AGENT_FACING_SMART_REPLY"] request = dialogflow_v2.UpdateDocumentRequest( document=document, @@ -59,4 +59,5 @@ def sample_update_document(): # Handle the response print(response) + # [END dialogflow_v2_generated_Documents_UpdateDocument_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_encryption_spec_service_get_encryption_spec_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_encryption_spec_service_get_encryption_spec_async.py index 9d1f80f1e546..ef43db8b7788 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_encryption_spec_service_get_encryption_spec_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_encryption_spec_service_get_encryption_spec_async.py @@ -49,4 +49,5 @@ async def sample_get_encryption_spec(): # Handle the response print(response) + # [END dialogflow_v2_generated_EncryptionSpecService_GetEncryptionSpec_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_encryption_spec_service_get_encryption_spec_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_encryption_spec_service_get_encryption_spec_sync.py index 197f73122ea8..fd968c19ea7a 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_encryption_spec_service_get_encryption_spec_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_encryption_spec_service_get_encryption_spec_sync.py @@ -49,4 +49,5 @@ def sample_get_encryption_spec(): # Handle the response print(response) + # [END dialogflow_v2_generated_EncryptionSpecService_GetEncryptionSpec_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_encryption_spec_service_initialize_encryption_spec_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_encryption_spec_service_initialize_encryption_spec_async.py index 56771f9f5776..637519030bda 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_encryption_spec_service_initialize_encryption_spec_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_encryption_spec_service_initialize_encryption_spec_async.py @@ -56,4 +56,5 @@ async def sample_initialize_encryption_spec(): # Handle the response print(response) + # [END dialogflow_v2_generated_EncryptionSpecService_InitializeEncryptionSpec_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_encryption_spec_service_initialize_encryption_spec_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_encryption_spec_service_initialize_encryption_spec_sync.py index f5458a0990a0..e214d36fb221 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_encryption_spec_service_initialize_encryption_spec_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_encryption_spec_service_initialize_encryption_spec_sync.py @@ -56,4 +56,5 @@ def sample_initialize_encryption_spec(): # Handle the response print(response) + # [END dialogflow_v2_generated_EncryptionSpecService_InitializeEncryptionSpec_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_create_entities_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_create_entities_async.py index 96fa95caf987..accea3ec843a 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_create_entities_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_create_entities_async.py @@ -41,7 +41,7 @@ async def sample_batch_create_entities(): # Initialize request argument(s) entities = dialogflow_v2.Entity() entities.value = "value_value" - entities.synonyms = ['synonyms_value1', 'synonyms_value2'] + entities.synonyms = ["synonyms_value1", "synonyms_value2"] request = dialogflow_v2.BatchCreateEntitiesRequest( parent="parent_value", @@ -58,4 +58,5 @@ async def sample_batch_create_entities(): # Handle the response print(response) + # [END dialogflow_v2_generated_EntityTypes_BatchCreateEntities_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_create_entities_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_create_entities_sync.py index 62ae57f1986d..97d0adf751e4 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_create_entities_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_create_entities_sync.py @@ -41,7 +41,7 @@ def sample_batch_create_entities(): # Initialize request argument(s) entities = dialogflow_v2.Entity() entities.value = "value_value" - entities.synonyms = ['synonyms_value1', 'synonyms_value2'] + entities.synonyms = ["synonyms_value1", "synonyms_value2"] request = dialogflow_v2.BatchCreateEntitiesRequest( parent="parent_value", @@ -58,4 +58,5 @@ def sample_batch_create_entities(): # Handle the response print(response) + # [END dialogflow_v2_generated_EntityTypes_BatchCreateEntities_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_delete_entities_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_delete_entities_async.py index 73136e933b22..dbd5c7c4775f 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_delete_entities_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_delete_entities_async.py @@ -41,7 +41,7 @@ async def sample_batch_delete_entities(): # Initialize request argument(s) request = dialogflow_v2.BatchDeleteEntitiesRequest( parent="parent_value", - entity_values=['entity_values_value1', 'entity_values_value2'], + entity_values=["entity_values_value1", "entity_values_value2"], ) # Make the request @@ -54,4 +54,5 @@ async def sample_batch_delete_entities(): # Handle the response print(response) + # [END dialogflow_v2_generated_EntityTypes_BatchDeleteEntities_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_delete_entities_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_delete_entities_sync.py index b7bb11c9c6da..49118722af56 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_delete_entities_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_delete_entities_sync.py @@ -41,7 +41,7 @@ def sample_batch_delete_entities(): # Initialize request argument(s) request = dialogflow_v2.BatchDeleteEntitiesRequest( parent="parent_value", - entity_values=['entity_values_value1', 'entity_values_value2'], + entity_values=["entity_values_value1", "entity_values_value2"], ) # Make the request @@ -54,4 +54,5 @@ def sample_batch_delete_entities(): # Handle the response print(response) + # [END dialogflow_v2_generated_EntityTypes_BatchDeleteEntities_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_delete_entity_types_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_delete_entity_types_async.py index b2a3ceb7f22f..d0062f585797 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_delete_entity_types_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_delete_entity_types_async.py @@ -41,7 +41,7 @@ async def sample_batch_delete_entity_types(): # Initialize request argument(s) request = dialogflow_v2.BatchDeleteEntityTypesRequest( parent="parent_value", - entity_type_names=['entity_type_names_value1', 'entity_type_names_value2'], + entity_type_names=["entity_type_names_value1", "entity_type_names_value2"], ) # Make the request @@ -54,4 +54,5 @@ async def sample_batch_delete_entity_types(): # Handle the response print(response) + # [END dialogflow_v2_generated_EntityTypes_BatchDeleteEntityTypes_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_delete_entity_types_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_delete_entity_types_sync.py index c3c542e2bbae..c4e8c12ac8a0 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_delete_entity_types_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_delete_entity_types_sync.py @@ -41,7 +41,7 @@ def sample_batch_delete_entity_types(): # Initialize request argument(s) request = dialogflow_v2.BatchDeleteEntityTypesRequest( parent="parent_value", - entity_type_names=['entity_type_names_value1', 'entity_type_names_value2'], + entity_type_names=["entity_type_names_value1", "entity_type_names_value2"], ) # Make the request @@ -54,4 +54,5 @@ def sample_batch_delete_entity_types(): # Handle the response print(response) + # [END dialogflow_v2_generated_EntityTypes_BatchDeleteEntityTypes_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_update_entities_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_update_entities_async.py index 4c423559da55..0658fb71f8da 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_update_entities_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_update_entities_async.py @@ -41,7 +41,7 @@ async def sample_batch_update_entities(): # Initialize request argument(s) entities = dialogflow_v2.Entity() entities.value = "value_value" - entities.synonyms = ['synonyms_value1', 'synonyms_value2'] + entities.synonyms = ["synonyms_value1", "synonyms_value2"] request = dialogflow_v2.BatchUpdateEntitiesRequest( parent="parent_value", @@ -58,4 +58,5 @@ async def sample_batch_update_entities(): # Handle the response print(response) + # [END dialogflow_v2_generated_EntityTypes_BatchUpdateEntities_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_update_entities_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_update_entities_sync.py index e7e40ee06595..abd9ff192af5 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_update_entities_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_update_entities_sync.py @@ -41,7 +41,7 @@ def sample_batch_update_entities(): # Initialize request argument(s) entities = dialogflow_v2.Entity() entities.value = "value_value" - entities.synonyms = ['synonyms_value1', 'synonyms_value2'] + entities.synonyms = ["synonyms_value1", "synonyms_value2"] request = dialogflow_v2.BatchUpdateEntitiesRequest( parent="parent_value", @@ -58,4 +58,5 @@ def sample_batch_update_entities(): # Handle the response print(response) + # [END dialogflow_v2_generated_EntityTypes_BatchUpdateEntities_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_update_entity_types_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_update_entity_types_async.py index e6e73a966d8b..7ae812083232 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_update_entity_types_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_update_entity_types_async.py @@ -54,4 +54,5 @@ async def sample_batch_update_entity_types(): # Handle the response print(response) + # [END dialogflow_v2_generated_EntityTypes_BatchUpdateEntityTypes_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_update_entity_types_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_update_entity_types_sync.py index 7960db1b9b6d..5d4733393018 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_update_entity_types_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_batch_update_entity_types_sync.py @@ -54,4 +54,5 @@ def sample_batch_update_entity_types(): # Handle the response print(response) + # [END dialogflow_v2_generated_EntityTypes_BatchUpdateEntityTypes_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_create_entity_type_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_create_entity_type_async.py index bb5c960fc085..44f0d66c9c40 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_create_entity_type_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_create_entity_type_async.py @@ -54,4 +54,5 @@ async def sample_create_entity_type(): # Handle the response print(response) + # [END dialogflow_v2_generated_EntityTypes_CreateEntityType_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_create_entity_type_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_create_entity_type_sync.py index ece92f046b68..54879f19066e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_create_entity_type_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_create_entity_type_sync.py @@ -54,4 +54,5 @@ def sample_create_entity_type(): # Handle the response print(response) + # [END dialogflow_v2_generated_EntityTypes_CreateEntityType_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_get_entity_type_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_get_entity_type_async.py index f7bd34eda561..417931af336c 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_get_entity_type_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_get_entity_type_async.py @@ -49,4 +49,5 @@ async def sample_get_entity_type(): # Handle the response print(response) + # [END dialogflow_v2_generated_EntityTypes_GetEntityType_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_get_entity_type_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_get_entity_type_sync.py index a526fe4c6ad2..72505bf52182 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_get_entity_type_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_get_entity_type_sync.py @@ -49,4 +49,5 @@ def sample_get_entity_type(): # Handle the response print(response) + # [END dialogflow_v2_generated_EntityTypes_GetEntityType_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_list_entity_types_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_list_entity_types_async.py index e35c1e953705..a1c79e6af602 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_list_entity_types_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_list_entity_types_async.py @@ -50,4 +50,5 @@ async def sample_list_entity_types(): async for response in page_result: print(response) + # [END dialogflow_v2_generated_EntityTypes_ListEntityTypes_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_list_entity_types_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_list_entity_types_sync.py index 3d41265c0c1d..ef19fa525840 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_list_entity_types_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_list_entity_types_sync.py @@ -50,4 +50,5 @@ def sample_list_entity_types(): for response in page_result: print(response) + # [END dialogflow_v2_generated_EntityTypes_ListEntityTypes_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_update_entity_type_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_update_entity_type_async.py index 973905b42c2f..a1b634edfcd0 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_update_entity_type_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_update_entity_type_async.py @@ -53,4 +53,5 @@ async def sample_update_entity_type(): # Handle the response print(response) + # [END dialogflow_v2_generated_EntityTypes_UpdateEntityType_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_update_entity_type_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_update_entity_type_sync.py index 79086407f161..7a9ffae1d2ea 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_update_entity_type_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_entity_types_update_entity_type_sync.py @@ -53,4 +53,5 @@ def sample_update_entity_type(): # Handle the response print(response) + # [END dialogflow_v2_generated_EntityTypes_UpdateEntityType_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_create_environment_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_create_environment_async.py index 99f883a88253..2c26200f18b7 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_create_environment_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_create_environment_async.py @@ -50,4 +50,5 @@ async def sample_create_environment(): # Handle the response print(response) + # [END dialogflow_v2_generated_Environments_CreateEnvironment_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_create_environment_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_create_environment_sync.py index 478da3d63ca2..aa0715ed0873 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_create_environment_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_create_environment_sync.py @@ -50,4 +50,5 @@ def sample_create_environment(): # Handle the response print(response) + # [END dialogflow_v2_generated_Environments_CreateEnvironment_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_get_environment_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_get_environment_async.py index 148ae7d3c0d1..2220f4055688 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_get_environment_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_get_environment_async.py @@ -49,4 +49,5 @@ async def sample_get_environment(): # Handle the response print(response) + # [END dialogflow_v2_generated_Environments_GetEnvironment_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_get_environment_history_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_get_environment_history_async.py index b07d03d664e1..7390d3644215 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_get_environment_history_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_get_environment_history_async.py @@ -50,4 +50,5 @@ async def sample_get_environment_history(): async for response in page_result: print(response) + # [END dialogflow_v2_generated_Environments_GetEnvironmentHistory_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_get_environment_history_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_get_environment_history_sync.py index bf9c7a9fa63b..4a5c898e8b0c 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_get_environment_history_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_get_environment_history_sync.py @@ -50,4 +50,5 @@ def sample_get_environment_history(): for response in page_result: print(response) + # [END dialogflow_v2_generated_Environments_GetEnvironmentHistory_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_get_environment_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_get_environment_sync.py index b93c11ede467..0f077e7b4e11 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_get_environment_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_get_environment_sync.py @@ -49,4 +49,5 @@ def sample_get_environment(): # Handle the response print(response) + # [END dialogflow_v2_generated_Environments_GetEnvironment_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_list_environments_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_list_environments_async.py index ae9123499a84..f40104b5df45 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_list_environments_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_list_environments_async.py @@ -50,4 +50,5 @@ async def sample_list_environments(): async for response in page_result: print(response) + # [END dialogflow_v2_generated_Environments_ListEnvironments_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_list_environments_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_list_environments_sync.py index e8bb3071eaeb..018da3052844 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_list_environments_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_list_environments_sync.py @@ -50,4 +50,5 @@ def sample_list_environments(): for response in page_result: print(response) + # [END dialogflow_v2_generated_Environments_ListEnvironments_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_update_environment_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_update_environment_async.py index 49152654df73..ae0d12f23a33 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_update_environment_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_update_environment_async.py @@ -39,8 +39,7 @@ async def sample_update_environment(): client = dialogflow_v2.EnvironmentsAsyncClient() # Initialize request argument(s) - request = dialogflow_v2.UpdateEnvironmentRequest( - ) + request = dialogflow_v2.UpdateEnvironmentRequest() # Make the request response = await client.update_environment(request=request) @@ -48,4 +47,5 @@ async def sample_update_environment(): # Handle the response print(response) + # [END dialogflow_v2_generated_Environments_UpdateEnvironment_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_update_environment_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_update_environment_sync.py index 285a96c06c0c..1c4861dacb69 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_update_environment_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_environments_update_environment_sync.py @@ -39,8 +39,7 @@ def sample_update_environment(): client = dialogflow_v2.EnvironmentsClient() # Initialize request argument(s) - request = dialogflow_v2.UpdateEnvironmentRequest( - ) + request = dialogflow_v2.UpdateEnvironmentRequest() # Make the request response = client.update_environment(request=request) @@ -48,4 +47,5 @@ def sample_update_environment(): # Handle the response print(response) + # [END dialogflow_v2_generated_Environments_UpdateEnvironment_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_fulfillments_get_fulfillment_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_fulfillments_get_fulfillment_async.py index 610884d017a1..b7fd4a81bcb3 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_fulfillments_get_fulfillment_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_fulfillments_get_fulfillment_async.py @@ -49,4 +49,5 @@ async def sample_get_fulfillment(): # Handle the response print(response) + # [END dialogflow_v2_generated_Fulfillments_GetFulfillment_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_fulfillments_get_fulfillment_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_fulfillments_get_fulfillment_sync.py index b49a55754e06..1ab5b97f6d02 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_fulfillments_get_fulfillment_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_fulfillments_get_fulfillment_sync.py @@ -49,4 +49,5 @@ def sample_get_fulfillment(): # Handle the response print(response) + # [END dialogflow_v2_generated_Fulfillments_GetFulfillment_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_fulfillments_update_fulfillment_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_fulfillments_update_fulfillment_async.py index 6a86a9db268a..dcd4da3ff01d 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_fulfillments_update_fulfillment_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_fulfillments_update_fulfillment_async.py @@ -53,4 +53,5 @@ async def sample_update_fulfillment(): # Handle the response print(response) + # [END dialogflow_v2_generated_Fulfillments_UpdateFulfillment_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_fulfillments_update_fulfillment_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_fulfillments_update_fulfillment_sync.py index 27be7540ff14..6adba7b8e183 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_fulfillments_update_fulfillment_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_fulfillments_update_fulfillment_sync.py @@ -53,4 +53,5 @@ def sample_update_fulfillment(): # Handle the response print(response) + # [END dialogflow_v2_generated_Fulfillments_UpdateFulfillment_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_create_generator_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_create_generator_async.py index 6a440c60f662..8b5f21cf6567 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_create_generator_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_create_generator_async.py @@ -53,4 +53,5 @@ async def sample_create_generator(): # Handle the response print(response) + # [END dialogflow_v2_generated_Generators_CreateGenerator_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_create_generator_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_create_generator_sync.py index e3a1a88b553f..aaf6f18ff0cd 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_create_generator_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_create_generator_sync.py @@ -53,4 +53,5 @@ def sample_create_generator(): # Handle the response print(response) + # [END dialogflow_v2_generated_Generators_CreateGenerator_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_get_generator_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_get_generator_async.py index bde7e9882007..5c69914ddad5 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_get_generator_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_get_generator_async.py @@ -49,4 +49,5 @@ async def sample_get_generator(): # Handle the response print(response) + # [END dialogflow_v2_generated_Generators_GetGenerator_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_get_generator_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_get_generator_sync.py index a414c4439cba..429b933fb80f 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_get_generator_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_get_generator_sync.py @@ -49,4 +49,5 @@ def sample_get_generator(): # Handle the response print(response) + # [END dialogflow_v2_generated_Generators_GetGenerator_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_list_generators_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_list_generators_async.py index 3c83a6d33ca4..42ee7e07b0c3 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_list_generators_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_list_generators_async.py @@ -50,4 +50,5 @@ async def sample_list_generators(): async for response in page_result: print(response) + # [END dialogflow_v2_generated_Generators_ListGenerators_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_list_generators_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_list_generators_sync.py index 44d695a2e74d..e727518e3140 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_list_generators_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_list_generators_sync.py @@ -50,4 +50,5 @@ def sample_list_generators(): for response in page_result: print(response) + # [END dialogflow_v2_generated_Generators_ListGenerators_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_update_generator_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_update_generator_async.py index 93f24f06f3e8..025ed8fc8338 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_update_generator_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_update_generator_async.py @@ -52,4 +52,5 @@ async def sample_update_generator(): # Handle the response print(response) + # [END dialogflow_v2_generated_Generators_UpdateGenerator_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_update_generator_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_update_generator_sync.py index 9072fb6f6319..802614cf3ea9 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_update_generator_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_generators_update_generator_sync.py @@ -52,4 +52,5 @@ def sample_update_generator(): # Handle the response print(response) + # [END dialogflow_v2_generated_Generators_UpdateGenerator_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_batch_delete_intents_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_batch_delete_intents_async.py index 67a1108d6316..70dcfc143631 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_batch_delete_intents_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_batch_delete_intents_async.py @@ -57,4 +57,5 @@ async def sample_batch_delete_intents(): # Handle the response print(response) + # [END dialogflow_v2_generated_Intents_BatchDeleteIntents_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_batch_delete_intents_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_batch_delete_intents_sync.py index 068009b44d26..7b748c2dc7bc 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_batch_delete_intents_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_batch_delete_intents_sync.py @@ -57,4 +57,5 @@ def sample_batch_delete_intents(): # Handle the response print(response) + # [END dialogflow_v2_generated_Intents_BatchDeleteIntents_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_batch_update_intents_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_batch_update_intents_async.py index 6c5ee4e32a9d..04d3a9b71764 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_batch_update_intents_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_batch_update_intents_async.py @@ -54,4 +54,5 @@ async def sample_batch_update_intents(): # Handle the response print(response) + # [END dialogflow_v2_generated_Intents_BatchUpdateIntents_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_batch_update_intents_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_batch_update_intents_sync.py index 232031e923fe..c82e934a6299 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_batch_update_intents_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_batch_update_intents_sync.py @@ -54,4 +54,5 @@ def sample_batch_update_intents(): # Handle the response print(response) + # [END dialogflow_v2_generated_Intents_BatchUpdateIntents_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_create_intent_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_create_intent_async.py index a78d13e10f09..c78e17f84482 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_create_intent_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_create_intent_async.py @@ -53,4 +53,5 @@ async def sample_create_intent(): # Handle the response print(response) + # [END dialogflow_v2_generated_Intents_CreateIntent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_create_intent_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_create_intent_sync.py index ece4c5077973..3b4faa643db8 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_create_intent_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_create_intent_sync.py @@ -53,4 +53,5 @@ def sample_create_intent(): # Handle the response print(response) + # [END dialogflow_v2_generated_Intents_CreateIntent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_get_intent_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_get_intent_async.py index 4e3484bcd8ec..3803c389c570 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_get_intent_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_get_intent_async.py @@ -49,4 +49,5 @@ async def sample_get_intent(): # Handle the response print(response) + # [END dialogflow_v2_generated_Intents_GetIntent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_get_intent_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_get_intent_sync.py index 1c96abc2f914..914772db4f52 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_get_intent_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_get_intent_sync.py @@ -49,4 +49,5 @@ def sample_get_intent(): # Handle the response print(response) + # [END dialogflow_v2_generated_Intents_GetIntent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_list_intents_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_list_intents_async.py index 8a46ab2bf9f7..c790a9f7b784 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_list_intents_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_list_intents_async.py @@ -50,4 +50,5 @@ async def sample_list_intents(): async for response in page_result: print(response) + # [END dialogflow_v2_generated_Intents_ListIntents_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_list_intents_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_list_intents_sync.py index 0f2229866a5b..dc90e51e9b26 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_list_intents_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_list_intents_sync.py @@ -50,4 +50,5 @@ def sample_list_intents(): for response in page_result: print(response) + # [END dialogflow_v2_generated_Intents_ListIntents_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_update_intent_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_update_intent_async.py index 33eccb621821..7fa7d2fbb077 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_update_intent_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_update_intent_async.py @@ -52,4 +52,5 @@ async def sample_update_intent(): # Handle the response print(response) + # [END dialogflow_v2_generated_Intents_UpdateIntent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_update_intent_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_update_intent_sync.py index bd9724eab72b..aff6f4ce4ca2 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_update_intent_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_intents_update_intent_sync.py @@ -52,4 +52,5 @@ def sample_update_intent(): # Handle the response print(response) + # [END dialogflow_v2_generated_Intents_UpdateIntent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_create_knowledge_base_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_create_knowledge_base_async.py index f39266f3f90c..8462f1753962 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_create_knowledge_base_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_create_knowledge_base_async.py @@ -53,4 +53,5 @@ async def sample_create_knowledge_base(): # Handle the response print(response) + # [END dialogflow_v2_generated_KnowledgeBases_CreateKnowledgeBase_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_create_knowledge_base_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_create_knowledge_base_sync.py index 7fe251cccd44..d0934f079d0c 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_create_knowledge_base_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_create_knowledge_base_sync.py @@ -53,4 +53,5 @@ def sample_create_knowledge_base(): # Handle the response print(response) + # [END dialogflow_v2_generated_KnowledgeBases_CreateKnowledgeBase_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_get_knowledge_base_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_get_knowledge_base_async.py index 717d624a2072..3fe7eed4b438 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_get_knowledge_base_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_get_knowledge_base_async.py @@ -49,4 +49,5 @@ async def sample_get_knowledge_base(): # Handle the response print(response) + # [END dialogflow_v2_generated_KnowledgeBases_GetKnowledgeBase_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_get_knowledge_base_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_get_knowledge_base_sync.py index a1a323f85bf1..6107e2d83919 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_get_knowledge_base_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_get_knowledge_base_sync.py @@ -49,4 +49,5 @@ def sample_get_knowledge_base(): # Handle the response print(response) + # [END dialogflow_v2_generated_KnowledgeBases_GetKnowledgeBase_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_list_knowledge_bases_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_list_knowledge_bases_async.py index ff555379aacd..413a0928a67a 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_list_knowledge_bases_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_list_knowledge_bases_async.py @@ -50,4 +50,5 @@ async def sample_list_knowledge_bases(): async for response in page_result: print(response) + # [END dialogflow_v2_generated_KnowledgeBases_ListKnowledgeBases_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_list_knowledge_bases_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_list_knowledge_bases_sync.py index 1142ed6119e4..8789c781f8f1 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_list_knowledge_bases_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_list_knowledge_bases_sync.py @@ -50,4 +50,5 @@ def sample_list_knowledge_bases(): for response in page_result: print(response) + # [END dialogflow_v2_generated_KnowledgeBases_ListKnowledgeBases_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_update_knowledge_base_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_update_knowledge_base_async.py index a83b3994ca57..edd1b5ef4097 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_update_knowledge_base_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_update_knowledge_base_async.py @@ -52,4 +52,5 @@ async def sample_update_knowledge_base(): # Handle the response print(response) + # [END dialogflow_v2_generated_KnowledgeBases_UpdateKnowledgeBase_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_update_knowledge_base_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_update_knowledge_base_sync.py index 901c31c204c7..53dbc5ad28c1 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_update_knowledge_base_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_knowledge_bases_update_knowledge_base_sync.py @@ -52,4 +52,5 @@ def sample_update_knowledge_base(): # Handle the response print(response) + # [END dialogflow_v2_generated_KnowledgeBases_UpdateKnowledgeBase_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_analyze_content_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_analyze_content_async.py index f7c32819b3c2..0054a5d178f9 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_analyze_content_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_analyze_content_async.py @@ -54,4 +54,5 @@ async def sample_analyze_content(): # Handle the response print(response) + # [END dialogflow_v2_generated_Participants_AnalyzeContent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_analyze_content_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_analyze_content_sync.py index 3fd210776c58..de107aaf3b22 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_analyze_content_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_analyze_content_sync.py @@ -54,4 +54,5 @@ def sample_analyze_content(): # Handle the response print(response) + # [END dialogflow_v2_generated_Participants_AnalyzeContent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_create_participant_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_create_participant_async.py index 2da2e5d4fcb0..fc0cf4156428 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_create_participant_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_create_participant_async.py @@ -49,4 +49,5 @@ async def sample_create_participant(): # Handle the response print(response) + # [END dialogflow_v2_generated_Participants_CreateParticipant_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_create_participant_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_create_participant_sync.py index 7dfb3b327d6b..868a72611d6a 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_create_participant_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_create_participant_sync.py @@ -49,4 +49,5 @@ def sample_create_participant(): # Handle the response print(response) + # [END dialogflow_v2_generated_Participants_CreateParticipant_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_get_participant_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_get_participant_async.py index 7f1bdf3c99c9..1c919f251d2b 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_get_participant_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_get_participant_async.py @@ -49,4 +49,5 @@ async def sample_get_participant(): # Handle the response print(response) + # [END dialogflow_v2_generated_Participants_GetParticipant_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_get_participant_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_get_participant_sync.py index 204842ceb218..09834401cc55 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_get_participant_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_get_participant_sync.py @@ -49,4 +49,5 @@ def sample_get_participant(): # Handle the response print(response) + # [END dialogflow_v2_generated_Participants_GetParticipant_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_list_participants_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_list_participants_async.py index ec9ebeaa17ef..5835b92e293f 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_list_participants_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_list_participants_async.py @@ -50,4 +50,5 @@ async def sample_list_participants(): async for response in page_result: print(response) + # [END dialogflow_v2_generated_Participants_ListParticipants_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_list_participants_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_list_participants_sync.py index aecd5bf595cf..f75a1979f1aa 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_list_participants_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_list_participants_sync.py @@ -50,4 +50,5 @@ def sample_list_participants(): for response in page_result: print(response) + # [END dialogflow_v2_generated_Participants_ListParticipants_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_streaming_analyze_content_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_streaming_analyze_content_async.py index 636f5f098936..09eee86c644f 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_streaming_analyze_content_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_streaming_analyze_content_async.py @@ -46,7 +46,7 @@ async def sample_streaming_analyze_content(): request = dialogflow_v2.StreamingAnalyzeContentRequest( audio_config=audio_config, - input_audio=b'input_audio_blob', + input_audio=b"input_audio_blob", participant="participant_value", ) @@ -67,4 +67,5 @@ def request_generator(): async for response in stream: print(response) + # [END dialogflow_v2_generated_Participants_StreamingAnalyzeContent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_streaming_analyze_content_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_streaming_analyze_content_sync.py index 832f538cea57..4554d1dcafec 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_streaming_analyze_content_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_streaming_analyze_content_sync.py @@ -46,7 +46,7 @@ def sample_streaming_analyze_content(): request = dialogflow_v2.StreamingAnalyzeContentRequest( audio_config=audio_config, - input_audio=b'input_audio_blob', + input_audio=b"input_audio_blob", participant="participant_value", ) @@ -67,4 +67,5 @@ def request_generator(): for response in stream: print(response) + # [END dialogflow_v2_generated_Participants_StreamingAnalyzeContent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_articles_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_articles_async.py index 2f204a7eefc4..6baa24789295 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_articles_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_articles_async.py @@ -49,4 +49,5 @@ async def sample_suggest_articles(): # Handle the response print(response) + # [END dialogflow_v2_generated_Participants_SuggestArticles_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_articles_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_articles_sync.py index f72c213ccc8e..6aafe575459f 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_articles_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_articles_sync.py @@ -49,4 +49,5 @@ def sample_suggest_articles(): # Handle the response print(response) + # [END dialogflow_v2_generated_Participants_SuggestArticles_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_faq_answers_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_faq_answers_async.py index c3a4dc5eef23..1f28a5efd5b6 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_faq_answers_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_faq_answers_async.py @@ -49,4 +49,5 @@ async def sample_suggest_faq_answers(): # Handle the response print(response) + # [END dialogflow_v2_generated_Participants_SuggestFaqAnswers_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_faq_answers_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_faq_answers_sync.py index 94163bc32797..4e78f61d0bf1 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_faq_answers_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_faq_answers_sync.py @@ -49,4 +49,5 @@ def sample_suggest_faq_answers(): # Handle the response print(response) + # [END dialogflow_v2_generated_Participants_SuggestFaqAnswers_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_knowledge_assist_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_knowledge_assist_async.py index 4e1f401153f0..f853e414a93a 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_knowledge_assist_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_knowledge_assist_async.py @@ -49,4 +49,5 @@ async def sample_suggest_knowledge_assist(): # Handle the response print(response) + # [END dialogflow_v2_generated_Participants_SuggestKnowledgeAssist_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_knowledge_assist_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_knowledge_assist_sync.py index 249aeb21b5c1..4ebf6c4377be 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_knowledge_assist_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_knowledge_assist_sync.py @@ -49,4 +49,5 @@ def sample_suggest_knowledge_assist(): # Handle the response print(response) + # [END dialogflow_v2_generated_Participants_SuggestKnowledgeAssist_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_smart_replies_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_smart_replies_async.py index 9c5611b4c24c..a30c7be09a28 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_smart_replies_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_smart_replies_async.py @@ -49,4 +49,5 @@ async def sample_suggest_smart_replies(): # Handle the response print(response) + # [END dialogflow_v2_generated_Participants_SuggestSmartReplies_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_smart_replies_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_smart_replies_sync.py index e7e52eb0f3a4..83cc00146c7d 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_smart_replies_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_suggest_smart_replies_sync.py @@ -49,4 +49,5 @@ def sample_suggest_smart_replies(): # Handle the response print(response) + # [END dialogflow_v2_generated_Participants_SuggestSmartReplies_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_update_participant_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_update_participant_async.py index cf89b5c954ad..65e28e2f1227 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_update_participant_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_update_participant_async.py @@ -39,8 +39,7 @@ async def sample_update_participant(): client = dialogflow_v2.ParticipantsAsyncClient() # Initialize request argument(s) - request = dialogflow_v2.UpdateParticipantRequest( - ) + request = dialogflow_v2.UpdateParticipantRequest() # Make the request response = await client.update_participant(request=request) @@ -48,4 +47,5 @@ async def sample_update_participant(): # Handle the response print(response) + # [END dialogflow_v2_generated_Participants_UpdateParticipant_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_update_participant_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_update_participant_sync.py index aacfd04adb2e..6e00a37e31e5 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_update_participant_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_participants_update_participant_sync.py @@ -39,8 +39,7 @@ def sample_update_participant(): client = dialogflow_v2.ParticipantsClient() # Initialize request argument(s) - request = dialogflow_v2.UpdateParticipantRequest( - ) + request = dialogflow_v2.UpdateParticipantRequest() # Make the request response = client.update_participant(request=request) @@ -48,4 +47,5 @@ def sample_update_participant(): # Handle the response print(response) + # [END dialogflow_v2_generated_Participants_UpdateParticipant_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_create_session_entity_type_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_create_session_entity_type_async.py index 77186c534a1c..86c2fc337a2e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_create_session_entity_type_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_create_session_entity_type_async.py @@ -43,7 +43,7 @@ async def sample_create_session_entity_type(): session_entity_type.name = "name_value" session_entity_type.entity_override_mode = "ENTITY_OVERRIDE_MODE_SUPPLEMENT" session_entity_type.entities.value = "value_value" - session_entity_type.entities.synonyms = ['synonyms_value1', 'synonyms_value2'] + session_entity_type.entities.synonyms = ["synonyms_value1", "synonyms_value2"] request = dialogflow_v2.CreateSessionEntityTypeRequest( parent="parent_value", @@ -56,4 +56,5 @@ async def sample_create_session_entity_type(): # Handle the response print(response) + # [END dialogflow_v2_generated_SessionEntityTypes_CreateSessionEntityType_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_create_session_entity_type_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_create_session_entity_type_sync.py index 0f2cfb40c2f8..8f3e3a9a4f7e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_create_session_entity_type_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_create_session_entity_type_sync.py @@ -43,7 +43,7 @@ def sample_create_session_entity_type(): session_entity_type.name = "name_value" session_entity_type.entity_override_mode = "ENTITY_OVERRIDE_MODE_SUPPLEMENT" session_entity_type.entities.value = "value_value" - session_entity_type.entities.synonyms = ['synonyms_value1', 'synonyms_value2'] + session_entity_type.entities.synonyms = ["synonyms_value1", "synonyms_value2"] request = dialogflow_v2.CreateSessionEntityTypeRequest( parent="parent_value", @@ -56,4 +56,5 @@ def sample_create_session_entity_type(): # Handle the response print(response) + # [END dialogflow_v2_generated_SessionEntityTypes_CreateSessionEntityType_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_get_session_entity_type_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_get_session_entity_type_async.py index 3ef9c00d16bf..bd562b4a9b82 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_get_session_entity_type_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_get_session_entity_type_async.py @@ -49,4 +49,5 @@ async def sample_get_session_entity_type(): # Handle the response print(response) + # [END dialogflow_v2_generated_SessionEntityTypes_GetSessionEntityType_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_get_session_entity_type_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_get_session_entity_type_sync.py index ea8cd0b5b4cd..ef7417c8d937 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_get_session_entity_type_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_get_session_entity_type_sync.py @@ -49,4 +49,5 @@ def sample_get_session_entity_type(): # Handle the response print(response) + # [END dialogflow_v2_generated_SessionEntityTypes_GetSessionEntityType_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_list_session_entity_types_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_list_session_entity_types_async.py index 7777bb5f3f9a..2ceff0076030 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_list_session_entity_types_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_list_session_entity_types_async.py @@ -50,4 +50,5 @@ async def sample_list_session_entity_types(): async for response in page_result: print(response) + # [END dialogflow_v2_generated_SessionEntityTypes_ListSessionEntityTypes_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_list_session_entity_types_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_list_session_entity_types_sync.py index 520f5f030e07..d1e177c4e72c 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_list_session_entity_types_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_list_session_entity_types_sync.py @@ -50,4 +50,5 @@ def sample_list_session_entity_types(): for response in page_result: print(response) + # [END dialogflow_v2_generated_SessionEntityTypes_ListSessionEntityTypes_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_update_session_entity_type_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_update_session_entity_type_async.py index ba8b7a8ffe25..7379dd6859aa 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_update_session_entity_type_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_update_session_entity_type_async.py @@ -43,7 +43,7 @@ async def sample_update_session_entity_type(): session_entity_type.name = "name_value" session_entity_type.entity_override_mode = "ENTITY_OVERRIDE_MODE_SUPPLEMENT" session_entity_type.entities.value = "value_value" - session_entity_type.entities.synonyms = ['synonyms_value1', 'synonyms_value2'] + session_entity_type.entities.synonyms = ["synonyms_value1", "synonyms_value2"] request = dialogflow_v2.UpdateSessionEntityTypeRequest( session_entity_type=session_entity_type, @@ -55,4 +55,5 @@ async def sample_update_session_entity_type(): # Handle the response print(response) + # [END dialogflow_v2_generated_SessionEntityTypes_UpdateSessionEntityType_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_update_session_entity_type_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_update_session_entity_type_sync.py index c271781f41b7..65be68a34001 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_update_session_entity_type_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_session_entity_types_update_session_entity_type_sync.py @@ -43,7 +43,7 @@ def sample_update_session_entity_type(): session_entity_type.name = "name_value" session_entity_type.entity_override_mode = "ENTITY_OVERRIDE_MODE_SUPPLEMENT" session_entity_type.entities.value = "value_value" - session_entity_type.entities.synonyms = ['synonyms_value1', 'synonyms_value2'] + session_entity_type.entities.synonyms = ["synonyms_value1", "synonyms_value2"] request = dialogflow_v2.UpdateSessionEntityTypeRequest( session_entity_type=session_entity_type, @@ -55,4 +55,5 @@ def sample_update_session_entity_type(): # Handle the response print(response) + # [END dialogflow_v2_generated_SessionEntityTypes_UpdateSessionEntityType_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_sessions_detect_intent_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_sessions_detect_intent_async.py index 14a10252a07d..098e119b10e2 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_sessions_detect_intent_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_sessions_detect_intent_async.py @@ -55,4 +55,5 @@ async def sample_detect_intent(): # Handle the response print(response) + # [END dialogflow_v2_generated_Sessions_DetectIntent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_sessions_detect_intent_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_sessions_detect_intent_sync.py index 8ad02da82ced..efe900cc56b1 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_sessions_detect_intent_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_sessions_detect_intent_sync.py @@ -55,4 +55,5 @@ def sample_detect_intent(): # Handle the response print(response) + # [END dialogflow_v2_generated_Sessions_DetectIntent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_sessions_streaming_detect_intent_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_sessions_streaming_detect_intent_async.py index 372a9ff505e9..d8021da2ed2b 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_sessions_streaming_detect_intent_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_sessions_streaming_detect_intent_async.py @@ -66,4 +66,5 @@ def request_generator(): async for response in stream: print(response) + # [END dialogflow_v2_generated_Sessions_StreamingDetectIntent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_sessions_streaming_detect_intent_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_sessions_streaming_detect_intent_sync.py index 42f060e544c0..b9ec2a9db936 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_sessions_streaming_detect_intent_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_sessions_streaming_detect_intent_sync.py @@ -66,4 +66,5 @@ def request_generator(): for response in stream: print(response) + # [END dialogflow_v2_generated_Sessions_StreamingDetectIntent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_create_version_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_create_version_async.py index eb9c41ef7413..8f685cdf3a71 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_create_version_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_create_version_async.py @@ -49,4 +49,5 @@ async def sample_create_version(): # Handle the response print(response) + # [END dialogflow_v2_generated_Versions_CreateVersion_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_create_version_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_create_version_sync.py index d82256ef705b..d9c117803fdf 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_create_version_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_create_version_sync.py @@ -49,4 +49,5 @@ def sample_create_version(): # Handle the response print(response) + # [END dialogflow_v2_generated_Versions_CreateVersion_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_get_version_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_get_version_async.py index ff2b1fff56e6..884d384aaf30 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_get_version_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_get_version_async.py @@ -49,4 +49,5 @@ async def sample_get_version(): # Handle the response print(response) + # [END dialogflow_v2_generated_Versions_GetVersion_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_get_version_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_get_version_sync.py index d0eb7ea63131..654d5982e86b 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_get_version_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_get_version_sync.py @@ -49,4 +49,5 @@ def sample_get_version(): # Handle the response print(response) + # [END dialogflow_v2_generated_Versions_GetVersion_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_list_versions_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_list_versions_async.py index f4a8e479763e..6ec741cda771 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_list_versions_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_list_versions_async.py @@ -50,4 +50,5 @@ async def sample_list_versions(): async for response in page_result: print(response) + # [END dialogflow_v2_generated_Versions_ListVersions_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_list_versions_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_list_versions_sync.py index 66f863b37218..318ea4f6c56e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_list_versions_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_list_versions_sync.py @@ -50,4 +50,5 @@ def sample_list_versions(): for response in page_result: print(response) + # [END dialogflow_v2_generated_Versions_ListVersions_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_update_version_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_update_version_async.py index 2cca423b4d31..355598d28ed5 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_update_version_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_update_version_async.py @@ -39,8 +39,7 @@ async def sample_update_version(): client = dialogflow_v2.VersionsAsyncClient() # Initialize request argument(s) - request = dialogflow_v2.UpdateVersionRequest( - ) + request = dialogflow_v2.UpdateVersionRequest() # Make the request response = await client.update_version(request=request) @@ -48,4 +47,5 @@ async def sample_update_version(): # Handle the response print(response) + # [END dialogflow_v2_generated_Versions_UpdateVersion_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_update_version_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_update_version_sync.py index ad4efbe2fa37..c7f5ee7b3614 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_update_version_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2_generated_versions_update_version_sync.py @@ -39,8 +39,7 @@ def sample_update_version(): client = dialogflow_v2.VersionsClient() # Initialize request argument(s) - request = dialogflow_v2.UpdateVersionRequest( - ) + request = dialogflow_v2.UpdateVersionRequest() # Make the request response = client.update_version(request=request) @@ -48,4 +47,5 @@ def sample_update_version(): # Handle the response print(response) + # [END dialogflow_v2_generated_Versions_UpdateVersion_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_export_agent_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_export_agent_async.py index fe5a74e433dd..b9d4cbc0f717 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_export_agent_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_export_agent_async.py @@ -53,4 +53,5 @@ async def sample_export_agent(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Agents_ExportAgent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_export_agent_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_export_agent_sync.py index 10ac8166bdf6..0b9a8cdf3554 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_export_agent_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_export_agent_sync.py @@ -53,4 +53,5 @@ def sample_export_agent(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Agents_ExportAgent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_get_agent_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_get_agent_async.py index 39eb7b74a434..4b545b75aaf7 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_get_agent_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_get_agent_async.py @@ -49,4 +49,5 @@ async def sample_get_agent(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Agents_GetAgent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_get_agent_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_get_agent_sync.py index c29b02ed752e..565d0e858257 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_get_agent_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_get_agent_sync.py @@ -49,4 +49,5 @@ def sample_get_agent(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Agents_GetAgent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_get_validation_result_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_get_validation_result_async.py index 7d0da9ecc6d5..3eb229be7a28 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_get_validation_result_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_get_validation_result_async.py @@ -49,4 +49,5 @@ async def sample_get_validation_result(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Agents_GetValidationResult_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_get_validation_result_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_get_validation_result_sync.py index c7eb0ecd13e2..d515b708bf26 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_get_validation_result_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_get_validation_result_sync.py @@ -49,4 +49,5 @@ def sample_get_validation_result(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Agents_GetValidationResult_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_import_agent_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_import_agent_async.py index 8767d8744e54..66d985e70e03 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_import_agent_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_import_agent_async.py @@ -54,4 +54,5 @@ async def sample_import_agent(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Agents_ImportAgent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_import_agent_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_import_agent_sync.py index e962463b26a5..75b92010e3c1 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_import_agent_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_import_agent_sync.py @@ -54,4 +54,5 @@ def sample_import_agent(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Agents_ImportAgent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_restore_agent_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_restore_agent_async.py index d265f3e2d6cf..b420abf38cda 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_restore_agent_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_restore_agent_async.py @@ -54,4 +54,5 @@ async def sample_restore_agent(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Agents_RestoreAgent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_restore_agent_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_restore_agent_sync.py index cdc4423401f6..cffcf9fd467f 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_restore_agent_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_restore_agent_sync.py @@ -54,4 +54,5 @@ def sample_restore_agent(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Agents_RestoreAgent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_search_agents_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_search_agents_async.py index 0679dd1dab1f..1a0ad7f7125d 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_search_agents_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_search_agents_async.py @@ -50,4 +50,5 @@ async def sample_search_agents(): async for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Agents_SearchAgents_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_search_agents_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_search_agents_sync.py index 85c8569203c8..cead60900a02 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_search_agents_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_search_agents_sync.py @@ -50,4 +50,5 @@ def sample_search_agents(): for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Agents_SearchAgents_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_set_agent_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_set_agent_async.py index a7f437623c15..0eb88fb1260e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_set_agent_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_set_agent_async.py @@ -52,4 +52,5 @@ async def sample_set_agent(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Agents_SetAgent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_set_agent_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_set_agent_sync.py index 2d8fedcb3884..17dbc9779e93 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_set_agent_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_set_agent_sync.py @@ -52,4 +52,5 @@ def sample_set_agent(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Agents_SetAgent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_train_agent_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_train_agent_async.py index 106cf43f83fb..59ce34a09456 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_train_agent_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_train_agent_async.py @@ -53,4 +53,5 @@ async def sample_train_agent(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Agents_TrainAgent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_train_agent_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_train_agent_sync.py index efc68beab5d0..fb2402b15b08 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_train_agent_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_agents_train_agent_sync.py @@ -53,4 +53,5 @@ def sample_train_agent(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Agents_TrainAgent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_get_answer_record_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_get_answer_record_async.py index 376701b1ecc7..7b8c75ffb65c 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_get_answer_record_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_get_answer_record_async.py @@ -39,8 +39,7 @@ async def sample_get_answer_record(): client = dialogflow_v2beta1.AnswerRecordsAsyncClient() # Initialize request argument(s) - request = dialogflow_v2beta1.GetAnswerRecordRequest( - ) + request = dialogflow_v2beta1.GetAnswerRecordRequest() # Make the request response = await client.get_answer_record(request=request) @@ -48,4 +47,5 @@ async def sample_get_answer_record(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_AnswerRecords_GetAnswerRecord_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_get_answer_record_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_get_answer_record_sync.py index efe12a7e782e..f00f11d2b483 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_get_answer_record_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_get_answer_record_sync.py @@ -39,8 +39,7 @@ def sample_get_answer_record(): client = dialogflow_v2beta1.AnswerRecordsClient() # Initialize request argument(s) - request = dialogflow_v2beta1.GetAnswerRecordRequest( - ) + request = dialogflow_v2beta1.GetAnswerRecordRequest() # Make the request response = client.get_answer_record(request=request) @@ -48,4 +47,5 @@ def sample_get_answer_record(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_AnswerRecords_GetAnswerRecord_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_list_answer_records_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_list_answer_records_async.py index 2fe7d186d73c..079a2c295ab0 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_list_answer_records_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_list_answer_records_async.py @@ -39,8 +39,7 @@ async def sample_list_answer_records(): client = dialogflow_v2beta1.AnswerRecordsAsyncClient() # Initialize request argument(s) - request = dialogflow_v2beta1.ListAnswerRecordsRequest( - ) + request = dialogflow_v2beta1.ListAnswerRecordsRequest() # Make the request page_result = client.list_answer_records(request=request) @@ -49,4 +48,5 @@ async def sample_list_answer_records(): async for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_AnswerRecords_ListAnswerRecords_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_list_answer_records_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_list_answer_records_sync.py index 7a84c8766984..46b0c7ac1c92 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_list_answer_records_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_list_answer_records_sync.py @@ -39,8 +39,7 @@ def sample_list_answer_records(): client = dialogflow_v2beta1.AnswerRecordsClient() # Initialize request argument(s) - request = dialogflow_v2beta1.ListAnswerRecordsRequest( - ) + request = dialogflow_v2beta1.ListAnswerRecordsRequest() # Make the request page_result = client.list_answer_records(request=request) @@ -49,4 +48,5 @@ def sample_list_answer_records(): for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_AnswerRecords_ListAnswerRecords_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_update_answer_record_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_update_answer_record_async.py index 39e58183fd74..dc0952e98e25 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_update_answer_record_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_update_answer_record_async.py @@ -39,8 +39,7 @@ async def sample_update_answer_record(): client = dialogflow_v2beta1.AnswerRecordsAsyncClient() # Initialize request argument(s) - request = dialogflow_v2beta1.UpdateAnswerRecordRequest( - ) + request = dialogflow_v2beta1.UpdateAnswerRecordRequest() # Make the request response = await client.update_answer_record(request=request) @@ -48,4 +47,5 @@ async def sample_update_answer_record(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_AnswerRecords_UpdateAnswerRecord_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_update_answer_record_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_update_answer_record_sync.py index e3537810ad31..1e323ace0b6e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_update_answer_record_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_answer_records_update_answer_record_sync.py @@ -39,8 +39,7 @@ def sample_update_answer_record(): client = dialogflow_v2beta1.AnswerRecordsClient() # Initialize request argument(s) - request = dialogflow_v2beta1.UpdateAnswerRecordRequest( - ) + request = dialogflow_v2beta1.UpdateAnswerRecordRequest() # Make the request response = client.update_answer_record(request=request) @@ -48,4 +47,5 @@ def sample_update_answer_record(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_AnswerRecords_UpdateAnswerRecord_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_create_context_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_create_context_async.py index 7ff6b131409b..290bb6fa1409 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_create_context_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_create_context_async.py @@ -49,4 +49,5 @@ async def sample_create_context(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Contexts_CreateContext_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_create_context_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_create_context_sync.py index 762d754fe24e..b798f5afb04e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_create_context_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_create_context_sync.py @@ -49,4 +49,5 @@ def sample_create_context(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Contexts_CreateContext_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_get_context_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_get_context_async.py index e822d8b6a529..16e50d4c5465 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_get_context_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_get_context_async.py @@ -49,4 +49,5 @@ async def sample_get_context(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Contexts_GetContext_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_get_context_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_get_context_sync.py index b075faddad4a..0706ce256c38 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_get_context_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_get_context_sync.py @@ -49,4 +49,5 @@ def sample_get_context(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Contexts_GetContext_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_list_contexts_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_list_contexts_async.py index 1eba77ff0fb5..6f34fb423160 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_list_contexts_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_list_contexts_async.py @@ -50,4 +50,5 @@ async def sample_list_contexts(): async for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Contexts_ListContexts_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_list_contexts_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_list_contexts_sync.py index 9f7b46fab9db..8f947f72f456 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_list_contexts_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_list_contexts_sync.py @@ -50,4 +50,5 @@ def sample_list_contexts(): for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Contexts_ListContexts_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_update_context_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_update_context_async.py index c8d6c14aad9c..77b7f97d7ef0 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_update_context_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_update_context_async.py @@ -39,8 +39,7 @@ async def sample_update_context(): client = dialogflow_v2beta1.ContextsAsyncClient() # Initialize request argument(s) - request = dialogflow_v2beta1.UpdateContextRequest( - ) + request = dialogflow_v2beta1.UpdateContextRequest() # Make the request response = await client.update_context(request=request) @@ -48,4 +47,5 @@ async def sample_update_context(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Contexts_UpdateContext_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_update_context_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_update_context_sync.py index f007e306125d..19cc24193126 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_update_context_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_contexts_update_context_sync.py @@ -39,8 +39,7 @@ def sample_update_context(): client = dialogflow_v2beta1.ContextsClient() # Initialize request argument(s) - request = dialogflow_v2beta1.UpdateContextRequest( - ) + request = dialogflow_v2beta1.UpdateContextRequest() # Make the request response = client.update_context(request=request) @@ -48,4 +47,5 @@ def sample_update_context(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Contexts_UpdateContext_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_clear_suggestion_feature_config_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_clear_suggestion_feature_config_async.py index ef167f99c20c..cb11e13ed977 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_clear_suggestion_feature_config_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_clear_suggestion_feature_config_async.py @@ -55,4 +55,5 @@ async def sample_clear_suggestion_feature_config(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_ConversationProfiles_ClearSuggestionFeatureConfig_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_clear_suggestion_feature_config_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_clear_suggestion_feature_config_sync.py index 835102c96b96..4beab9c65eac 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_clear_suggestion_feature_config_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_clear_suggestion_feature_config_sync.py @@ -55,4 +55,5 @@ def sample_clear_suggestion_feature_config(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_ConversationProfiles_ClearSuggestionFeatureConfig_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_create_conversation_profile_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_create_conversation_profile_async.py index d7e4791d33d7..a7e9bcd0b4f7 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_create_conversation_profile_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_create_conversation_profile_async.py @@ -53,4 +53,5 @@ async def sample_create_conversation_profile(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_ConversationProfiles_CreateConversationProfile_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_create_conversation_profile_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_create_conversation_profile_sync.py index 9010ea18c463..6a6f60383126 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_create_conversation_profile_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_create_conversation_profile_sync.py @@ -53,4 +53,5 @@ def sample_create_conversation_profile(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_ConversationProfiles_CreateConversationProfile_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_get_conversation_profile_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_get_conversation_profile_async.py index f744d9673a20..95773248d9b8 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_get_conversation_profile_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_get_conversation_profile_async.py @@ -49,4 +49,5 @@ async def sample_get_conversation_profile(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_ConversationProfiles_GetConversationProfile_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_get_conversation_profile_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_get_conversation_profile_sync.py index d703102333fb..8e28ad914a42 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_get_conversation_profile_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_get_conversation_profile_sync.py @@ -49,4 +49,5 @@ def sample_get_conversation_profile(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_ConversationProfiles_GetConversationProfile_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_list_conversation_profiles_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_list_conversation_profiles_async.py index f57d019c4607..d6d4d90fd003 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_list_conversation_profiles_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_list_conversation_profiles_async.py @@ -50,4 +50,5 @@ async def sample_list_conversation_profiles(): async for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_ConversationProfiles_ListConversationProfiles_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_list_conversation_profiles_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_list_conversation_profiles_sync.py index 916f1fb40308..e6caccc956f4 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_list_conversation_profiles_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_list_conversation_profiles_sync.py @@ -50,4 +50,5 @@ def sample_list_conversation_profiles(): for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_ConversationProfiles_ListConversationProfiles_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_set_suggestion_feature_config_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_set_suggestion_feature_config_async.py index 86ad609a7849..b1a562f25ebf 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_set_suggestion_feature_config_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_set_suggestion_feature_config_async.py @@ -54,4 +54,5 @@ async def sample_set_suggestion_feature_config(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_ConversationProfiles_SetSuggestionFeatureConfig_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_set_suggestion_feature_config_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_set_suggestion_feature_config_sync.py index c985ec68614d..6db43eaf37d1 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_set_suggestion_feature_config_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_set_suggestion_feature_config_sync.py @@ -54,4 +54,5 @@ def sample_set_suggestion_feature_config(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_ConversationProfiles_SetSuggestionFeatureConfig_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_update_conversation_profile_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_update_conversation_profile_async.py index 0dcc7ca53f2b..e239bdd97580 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_update_conversation_profile_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_update_conversation_profile_async.py @@ -52,4 +52,5 @@ async def sample_update_conversation_profile(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_ConversationProfiles_UpdateConversationProfile_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_update_conversation_profile_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_update_conversation_profile_sync.py index aa9a381792e8..abb2e3dce37e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_update_conversation_profile_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversation_profiles_update_conversation_profile_sync.py @@ -52,4 +52,5 @@ def sample_update_conversation_profile(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_ConversationProfiles_UpdateConversationProfile_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_batch_create_messages_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_batch_create_messages_async.py index 14994b63c203..8f6b3b53f69e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_batch_create_messages_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_batch_create_messages_async.py @@ -54,4 +54,5 @@ async def sample_batch_create_messages(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Conversations_BatchCreateMessages_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_batch_create_messages_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_batch_create_messages_sync.py index 55604c98f841..ea15457add32 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_batch_create_messages_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_batch_create_messages_sync.py @@ -54,4 +54,5 @@ def sample_batch_create_messages(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Conversations_BatchCreateMessages_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_complete_conversation_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_complete_conversation_async.py index 194d8be710cd..e205934226c9 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_complete_conversation_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_complete_conversation_async.py @@ -49,4 +49,5 @@ async def sample_complete_conversation(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Conversations_CompleteConversation_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_complete_conversation_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_complete_conversation_sync.py index a67309bfc07a..c1c855c0a3e1 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_complete_conversation_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_complete_conversation_sync.py @@ -49,4 +49,5 @@ def sample_complete_conversation(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Conversations_CompleteConversation_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_create_conversation_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_create_conversation_async.py index 87b634fc27e1..b06cafa60210 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_create_conversation_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_create_conversation_async.py @@ -53,4 +53,5 @@ async def sample_create_conversation(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Conversations_CreateConversation_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_create_conversation_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_create_conversation_sync.py index 4d512b830d78..d4dd5e5753cb 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_create_conversation_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_create_conversation_sync.py @@ -53,4 +53,5 @@ def sample_create_conversation(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Conversations_CreateConversation_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_stateless_suggestion_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_stateless_suggestion_async.py index 7d954e2fb534..0f37808bec3d 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_stateless_suggestion_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_stateless_suggestion_async.py @@ -53,4 +53,5 @@ async def sample_generate_stateless_suggestion(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Conversations_GenerateStatelessSuggestion_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_stateless_suggestion_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_stateless_suggestion_sync.py index cd3056e7761b..8b757074c8ec 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_stateless_suggestion_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_stateless_suggestion_sync.py @@ -53,4 +53,5 @@ def sample_generate_stateless_suggestion(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Conversations_GenerateStatelessSuggestion_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_stateless_summary_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_stateless_summary_async.py index c8369a5a63e3..bedcad4b6c73 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_stateless_summary_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_stateless_summary_async.py @@ -57,4 +57,5 @@ async def sample_generate_stateless_summary(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Conversations_GenerateStatelessSummary_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_stateless_summary_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_stateless_summary_sync.py index 46311c2950ff..c604007f2ac4 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_stateless_summary_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_stateless_summary_sync.py @@ -57,4 +57,5 @@ def sample_generate_stateless_summary(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Conversations_GenerateStatelessSummary_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_suggestions_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_suggestions_async.py index bd4f382fc978..d27d8ea14458 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_suggestions_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_suggestions_async.py @@ -49,4 +49,5 @@ async def sample_generate_suggestions(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Conversations_GenerateSuggestions_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_suggestions_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_suggestions_sync.py index 7e1b34663ed2..8d8548fab144 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_suggestions_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_generate_suggestions_sync.py @@ -49,4 +49,5 @@ def sample_generate_suggestions(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Conversations_GenerateSuggestions_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_get_conversation_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_get_conversation_async.py index f8c49822e81d..d06edb9f1c94 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_get_conversation_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_get_conversation_async.py @@ -49,4 +49,5 @@ async def sample_get_conversation(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Conversations_GetConversation_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_get_conversation_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_get_conversation_sync.py index b7dba79faee1..2bb2568a621b 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_get_conversation_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_get_conversation_sync.py @@ -49,4 +49,5 @@ def sample_get_conversation(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Conversations_GetConversation_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_ingest_context_references_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_ingest_context_references_async.py index 955ac208c1c5..ddbb6fd94332 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_ingest_context_references_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_ingest_context_references_async.py @@ -49,4 +49,5 @@ async def sample_ingest_context_references(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Conversations_IngestContextReferences_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_ingest_context_references_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_ingest_context_references_sync.py index a590314a029e..bf4f89670398 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_ingest_context_references_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_ingest_context_references_sync.py @@ -49,4 +49,5 @@ def sample_ingest_context_references(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Conversations_IngestContextReferences_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_list_conversations_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_list_conversations_async.py index 72e243d380d9..3c2978036409 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_list_conversations_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_list_conversations_async.py @@ -50,4 +50,5 @@ async def sample_list_conversations(): async for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Conversations_ListConversations_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_list_conversations_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_list_conversations_sync.py index d7456d3c55c9..0335a7bdbee2 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_list_conversations_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_list_conversations_sync.py @@ -50,4 +50,5 @@ def sample_list_conversations(): for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Conversations_ListConversations_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_list_messages_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_list_messages_async.py index 01e3c85e09f8..a074b344aaa6 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_list_messages_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_list_messages_async.py @@ -50,4 +50,5 @@ async def sample_list_messages(): async for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Conversations_ListMessages_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_list_messages_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_list_messages_sync.py index e255daf45b18..b2cec1a8b980 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_list_messages_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_list_messages_sync.py @@ -50,4 +50,5 @@ def sample_list_messages(): for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Conversations_ListMessages_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_search_knowledge_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_search_knowledge_async.py index a1eb8bc218f3..5851ed5afb1e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_search_knowledge_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_search_knowledge_async.py @@ -51,4 +51,5 @@ async def sample_search_knowledge(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Conversations_SearchKnowledge_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_search_knowledge_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_search_knowledge_sync.py index aeb62c3d58ef..f550e3c1c730 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_search_knowledge_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_search_knowledge_sync.py @@ -51,4 +51,5 @@ def sample_search_knowledge(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Conversations_SearchKnowledge_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_suggest_conversation_summary_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_suggest_conversation_summary_async.py index b1554a3c9f07..6218f1572483 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_suggest_conversation_summary_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_suggest_conversation_summary_async.py @@ -49,4 +49,5 @@ async def sample_suggest_conversation_summary(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Conversations_SuggestConversationSummary_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_suggest_conversation_summary_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_suggest_conversation_summary_sync.py index e5bca1687913..a8a7f29068de 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_suggest_conversation_summary_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_conversations_suggest_conversation_summary_sync.py @@ -49,4 +49,5 @@ def sample_suggest_conversation_summary(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Conversations_SuggestConversationSummary_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_create_document_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_create_document_async.py index 8d00b2c81057..1faa67646968 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_create_document_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_create_document_async.py @@ -43,7 +43,7 @@ async def sample_create_document(): document.content_uri = "content_uri_value" document.display_name = "display_name_value" document.mime_type = "mime_type_value" - document.knowledge_types = ['SMART_REPLY'] + document.knowledge_types = ["SMART_REPLY"] request = dialogflow_v2beta1.CreateDocumentRequest( parent="parent_value", @@ -60,4 +60,5 @@ async def sample_create_document(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Documents_CreateDocument_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_create_document_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_create_document_sync.py index 82a080555026..17d8e09f37a8 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_create_document_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_create_document_sync.py @@ -43,7 +43,7 @@ def sample_create_document(): document.content_uri = "content_uri_value" document.display_name = "display_name_value" document.mime_type = "mime_type_value" - document.knowledge_types = ['SMART_REPLY'] + document.knowledge_types = ["SMART_REPLY"] request = dialogflow_v2beta1.CreateDocumentRequest( parent="parent_value", @@ -60,4 +60,5 @@ def sample_create_document(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Documents_CreateDocument_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_delete_document_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_delete_document_async.py index c594f2d859a5..4aeca447714b 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_delete_document_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_delete_document_async.py @@ -53,4 +53,5 @@ async def sample_delete_document(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Documents_DeleteDocument_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_delete_document_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_delete_document_sync.py index 73d7889d6713..795f90572829 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_delete_document_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_delete_document_sync.py @@ -53,4 +53,5 @@ def sample_delete_document(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Documents_DeleteDocument_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_get_document_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_get_document_async.py index d4e3bd476081..f1c2569eda29 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_get_document_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_get_document_async.py @@ -49,4 +49,5 @@ async def sample_get_document(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Documents_GetDocument_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_get_document_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_get_document_sync.py index c2ae7a33f4aa..ae359c621c85 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_get_document_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_get_document_sync.py @@ -49,4 +49,5 @@ def sample_get_document(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Documents_GetDocument_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_import_documents_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_import_documents_async.py index 1cef8ddcf5d6..19a1f1b92280 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_import_documents_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_import_documents_async.py @@ -40,11 +40,11 @@ async def sample_import_documents(): # Initialize request argument(s) gcs_source = dialogflow_v2beta1.GcsSources() - gcs_source.uris = ['uris_value1', 'uris_value2'] + gcs_source.uris = ["uris_value1", "uris_value2"] document_template = dialogflow_v2beta1.ImportDocumentTemplate() document_template.mime_type = "mime_type_value" - document_template.knowledge_types = ['SMART_REPLY'] + document_template.knowledge_types = ["SMART_REPLY"] request = dialogflow_v2beta1.ImportDocumentsRequest( gcs_source=gcs_source, @@ -62,4 +62,5 @@ async def sample_import_documents(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Documents_ImportDocuments_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_import_documents_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_import_documents_sync.py index 45c7e5044aaf..068f928912c2 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_import_documents_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_import_documents_sync.py @@ -40,11 +40,11 @@ def sample_import_documents(): # Initialize request argument(s) gcs_source = dialogflow_v2beta1.GcsSources() - gcs_source.uris = ['uris_value1', 'uris_value2'] + gcs_source.uris = ["uris_value1", "uris_value2"] document_template = dialogflow_v2beta1.ImportDocumentTemplate() document_template.mime_type = "mime_type_value" - document_template.knowledge_types = ['SMART_REPLY'] + document_template.knowledge_types = ["SMART_REPLY"] request = dialogflow_v2beta1.ImportDocumentsRequest( gcs_source=gcs_source, @@ -62,4 +62,5 @@ def sample_import_documents(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Documents_ImportDocuments_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_list_documents_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_list_documents_async.py index 210c277435e7..0dada8de254f 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_list_documents_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_list_documents_async.py @@ -50,4 +50,5 @@ async def sample_list_documents(): async for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Documents_ListDocuments_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_list_documents_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_list_documents_sync.py index ddcf2e914ce2..594a7389a319 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_list_documents_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_list_documents_sync.py @@ -50,4 +50,5 @@ def sample_list_documents(): for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Documents_ListDocuments_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_reload_document_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_reload_document_async.py index 7914578a25f7..d534443ad973 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_reload_document_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_reload_document_async.py @@ -53,4 +53,5 @@ async def sample_reload_document(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Documents_ReloadDocument_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_reload_document_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_reload_document_sync.py index 4efbc81d97cc..0f7b43a4ae5a 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_reload_document_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_reload_document_sync.py @@ -53,4 +53,5 @@ def sample_reload_document(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Documents_ReloadDocument_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_update_document_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_update_document_async.py index c0f3ae7a362e..fad92aca4a68 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_update_document_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_update_document_async.py @@ -43,7 +43,7 @@ async def sample_update_document(): document.content_uri = "content_uri_value" document.display_name = "display_name_value" document.mime_type = "mime_type_value" - document.knowledge_types = ['SMART_REPLY'] + document.knowledge_types = ["SMART_REPLY"] request = dialogflow_v2beta1.UpdateDocumentRequest( document=document, @@ -59,4 +59,5 @@ async def sample_update_document(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Documents_UpdateDocument_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_update_document_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_update_document_sync.py index d39d06e4aa6f..75ae0d4fbc6a 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_update_document_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_documents_update_document_sync.py @@ -43,7 +43,7 @@ def sample_update_document(): document.content_uri = "content_uri_value" document.display_name = "display_name_value" document.mime_type = "mime_type_value" - document.knowledge_types = ['SMART_REPLY'] + document.knowledge_types = ["SMART_REPLY"] request = dialogflow_v2beta1.UpdateDocumentRequest( document=document, @@ -59,4 +59,5 @@ def sample_update_document(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Documents_UpdateDocument_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_encryption_spec_service_get_encryption_spec_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_encryption_spec_service_get_encryption_spec_async.py index 4c8b3803b214..0d8d3f12d149 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_encryption_spec_service_get_encryption_spec_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_encryption_spec_service_get_encryption_spec_async.py @@ -49,4 +49,5 @@ async def sample_get_encryption_spec(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_EncryptionSpecService_GetEncryptionSpec_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_encryption_spec_service_get_encryption_spec_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_encryption_spec_service_get_encryption_spec_sync.py index 41111988a55b..b612fc94515f 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_encryption_spec_service_get_encryption_spec_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_encryption_spec_service_get_encryption_spec_sync.py @@ -49,4 +49,5 @@ def sample_get_encryption_spec(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_EncryptionSpecService_GetEncryptionSpec_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_encryption_spec_service_initialize_encryption_spec_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_encryption_spec_service_initialize_encryption_spec_async.py index 517c1cf84d48..3b4bdef01919 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_encryption_spec_service_initialize_encryption_spec_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_encryption_spec_service_initialize_encryption_spec_async.py @@ -56,4 +56,5 @@ async def sample_initialize_encryption_spec(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_EncryptionSpecService_InitializeEncryptionSpec_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_encryption_spec_service_initialize_encryption_spec_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_encryption_spec_service_initialize_encryption_spec_sync.py index 04ea307d469e..c5846245d762 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_encryption_spec_service_initialize_encryption_spec_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_encryption_spec_service_initialize_encryption_spec_sync.py @@ -56,4 +56,5 @@ def sample_initialize_encryption_spec(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_EncryptionSpecService_InitializeEncryptionSpec_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_create_entities_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_create_entities_async.py index 5ddc59f401aa..43345544856f 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_create_entities_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_create_entities_async.py @@ -57,4 +57,5 @@ async def sample_batch_create_entities(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_EntityTypes_BatchCreateEntities_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_create_entities_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_create_entities_sync.py index ad0123d510f5..c161e4d63706 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_create_entities_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_create_entities_sync.py @@ -57,4 +57,5 @@ def sample_batch_create_entities(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_EntityTypes_BatchCreateEntities_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_delete_entities_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_delete_entities_async.py index fab9d8c02028..27af48ddeaac 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_delete_entities_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_delete_entities_async.py @@ -41,7 +41,7 @@ async def sample_batch_delete_entities(): # Initialize request argument(s) request = dialogflow_v2beta1.BatchDeleteEntitiesRequest( parent="parent_value", - entity_values=['entity_values_value1', 'entity_values_value2'], + entity_values=["entity_values_value1", "entity_values_value2"], ) # Make the request @@ -54,4 +54,5 @@ async def sample_batch_delete_entities(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_EntityTypes_BatchDeleteEntities_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_delete_entities_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_delete_entities_sync.py index e0e4d35c1cbe..9362652775f4 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_delete_entities_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_delete_entities_sync.py @@ -41,7 +41,7 @@ def sample_batch_delete_entities(): # Initialize request argument(s) request = dialogflow_v2beta1.BatchDeleteEntitiesRequest( parent="parent_value", - entity_values=['entity_values_value1', 'entity_values_value2'], + entity_values=["entity_values_value1", "entity_values_value2"], ) # Make the request @@ -54,4 +54,5 @@ def sample_batch_delete_entities(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_EntityTypes_BatchDeleteEntities_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_delete_entity_types_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_delete_entity_types_async.py index be2d0c1343b0..7fe343e49e19 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_delete_entity_types_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_delete_entity_types_async.py @@ -41,7 +41,7 @@ async def sample_batch_delete_entity_types(): # Initialize request argument(s) request = dialogflow_v2beta1.BatchDeleteEntityTypesRequest( parent="parent_value", - entity_type_names=['entity_type_names_value1', 'entity_type_names_value2'], + entity_type_names=["entity_type_names_value1", "entity_type_names_value2"], ) # Make the request @@ -54,4 +54,5 @@ async def sample_batch_delete_entity_types(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_EntityTypes_BatchDeleteEntityTypes_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_delete_entity_types_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_delete_entity_types_sync.py index 3e7410f39c19..54b926e4152d 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_delete_entity_types_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_delete_entity_types_sync.py @@ -41,7 +41,7 @@ def sample_batch_delete_entity_types(): # Initialize request argument(s) request = dialogflow_v2beta1.BatchDeleteEntityTypesRequest( parent="parent_value", - entity_type_names=['entity_type_names_value1', 'entity_type_names_value2'], + entity_type_names=["entity_type_names_value1", "entity_type_names_value2"], ) # Make the request @@ -54,4 +54,5 @@ def sample_batch_delete_entity_types(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_EntityTypes_BatchDeleteEntityTypes_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_update_entities_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_update_entities_async.py index 1d95834f7c1f..2ed489c7bd99 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_update_entities_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_update_entities_async.py @@ -57,4 +57,5 @@ async def sample_batch_update_entities(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_EntityTypes_BatchUpdateEntities_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_update_entities_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_update_entities_sync.py index 994044eff88a..ae1d526b433e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_update_entities_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_update_entities_sync.py @@ -57,4 +57,5 @@ def sample_batch_update_entities(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_EntityTypes_BatchUpdateEntities_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_update_entity_types_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_update_entity_types_async.py index bf630e8da907..51064f029fb4 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_update_entity_types_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_update_entity_types_async.py @@ -54,4 +54,5 @@ async def sample_batch_update_entity_types(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_EntityTypes_BatchUpdateEntityTypes_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_update_entity_types_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_update_entity_types_sync.py index 4e571cea04a5..74790a3e21e8 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_update_entity_types_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_batch_update_entity_types_sync.py @@ -54,4 +54,5 @@ def sample_batch_update_entity_types(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_EntityTypes_BatchUpdateEntityTypes_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_create_entity_type_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_create_entity_type_async.py index 91012dbf223b..2e59af76dc12 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_create_entity_type_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_create_entity_type_async.py @@ -54,4 +54,5 @@ async def sample_create_entity_type(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_EntityTypes_CreateEntityType_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_create_entity_type_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_create_entity_type_sync.py index cff97e94cc7b..24d97c550b8e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_create_entity_type_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_create_entity_type_sync.py @@ -54,4 +54,5 @@ def sample_create_entity_type(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_EntityTypes_CreateEntityType_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_get_entity_type_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_get_entity_type_async.py index 35b5610fb572..6972203bd4ae 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_get_entity_type_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_get_entity_type_async.py @@ -49,4 +49,5 @@ async def sample_get_entity_type(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_EntityTypes_GetEntityType_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_get_entity_type_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_get_entity_type_sync.py index 5e6c4e959467..ef7d4993744f 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_get_entity_type_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_get_entity_type_sync.py @@ -49,4 +49,5 @@ def sample_get_entity_type(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_EntityTypes_GetEntityType_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_list_entity_types_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_list_entity_types_async.py index 47267fff9b53..b603bb4ae14c 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_list_entity_types_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_list_entity_types_async.py @@ -50,4 +50,5 @@ async def sample_list_entity_types(): async for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_EntityTypes_ListEntityTypes_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_list_entity_types_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_list_entity_types_sync.py index a33c428eb29a..bb545337663b 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_list_entity_types_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_list_entity_types_sync.py @@ -50,4 +50,5 @@ def sample_list_entity_types(): for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_EntityTypes_ListEntityTypes_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_update_entity_type_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_update_entity_type_async.py index 2afcd00e2f55..e6dfa932ffce 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_update_entity_type_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_update_entity_type_async.py @@ -53,4 +53,5 @@ async def sample_update_entity_type(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_EntityTypes_UpdateEntityType_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_update_entity_type_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_update_entity_type_sync.py index c0f487794cb1..0f54b801bed0 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_update_entity_type_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_entity_types_update_entity_type_sync.py @@ -53,4 +53,5 @@ def sample_update_entity_type(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_EntityTypes_UpdateEntityType_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_create_environment_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_create_environment_async.py index 1720b719b657..d690f74e119b 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_create_environment_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_create_environment_async.py @@ -50,4 +50,5 @@ async def sample_create_environment(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Environments_CreateEnvironment_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_create_environment_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_create_environment_sync.py index 5c5bed8fc4ce..8574243a0007 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_create_environment_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_create_environment_sync.py @@ -50,4 +50,5 @@ def sample_create_environment(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Environments_CreateEnvironment_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_get_environment_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_get_environment_async.py index 5f117937b160..59ca4e5b82c9 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_get_environment_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_get_environment_async.py @@ -49,4 +49,5 @@ async def sample_get_environment(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Environments_GetEnvironment_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_get_environment_history_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_get_environment_history_async.py index 5fa2b093fe0a..ddf3fd36d403 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_get_environment_history_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_get_environment_history_async.py @@ -50,4 +50,5 @@ async def sample_get_environment_history(): async for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Environments_GetEnvironmentHistory_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_get_environment_history_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_get_environment_history_sync.py index 7651965b82ae..43b4efa551b1 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_get_environment_history_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_get_environment_history_sync.py @@ -50,4 +50,5 @@ def sample_get_environment_history(): for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Environments_GetEnvironmentHistory_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_get_environment_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_get_environment_sync.py index fff4ad08052d..e809f8716c08 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_get_environment_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_get_environment_sync.py @@ -49,4 +49,5 @@ def sample_get_environment(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Environments_GetEnvironment_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_list_environments_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_list_environments_async.py index f8d6c6fe926e..6b0af831e63c 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_list_environments_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_list_environments_async.py @@ -50,4 +50,5 @@ async def sample_list_environments(): async for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Environments_ListEnvironments_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_list_environments_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_list_environments_sync.py index 3e1e1e09ab9b..fa3732e45507 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_list_environments_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_list_environments_sync.py @@ -50,4 +50,5 @@ def sample_list_environments(): for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Environments_ListEnvironments_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_update_environment_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_update_environment_async.py index ea22f3c3727c..ed72ffd461ab 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_update_environment_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_update_environment_async.py @@ -39,8 +39,7 @@ async def sample_update_environment(): client = dialogflow_v2beta1.EnvironmentsAsyncClient() # Initialize request argument(s) - request = dialogflow_v2beta1.UpdateEnvironmentRequest( - ) + request = dialogflow_v2beta1.UpdateEnvironmentRequest() # Make the request response = await client.update_environment(request=request) @@ -48,4 +47,5 @@ async def sample_update_environment(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Environments_UpdateEnvironment_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_update_environment_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_update_environment_sync.py index c8e8ba3bc3ac..9ad02ec9f4d8 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_update_environment_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_environments_update_environment_sync.py @@ -39,8 +39,7 @@ def sample_update_environment(): client = dialogflow_v2beta1.EnvironmentsClient() # Initialize request argument(s) - request = dialogflow_v2beta1.UpdateEnvironmentRequest( - ) + request = dialogflow_v2beta1.UpdateEnvironmentRequest() # Make the request response = client.update_environment(request=request) @@ -48,4 +47,5 @@ def sample_update_environment(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Environments_UpdateEnvironment_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_fulfillments_get_fulfillment_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_fulfillments_get_fulfillment_async.py index 392bc3b00720..81b3b53e2628 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_fulfillments_get_fulfillment_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_fulfillments_get_fulfillment_async.py @@ -49,4 +49,5 @@ async def sample_get_fulfillment(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Fulfillments_GetFulfillment_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_fulfillments_get_fulfillment_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_fulfillments_get_fulfillment_sync.py index 167cd9986332..6daac4d93b94 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_fulfillments_get_fulfillment_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_fulfillments_get_fulfillment_sync.py @@ -49,4 +49,5 @@ def sample_get_fulfillment(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Fulfillments_GetFulfillment_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_fulfillments_update_fulfillment_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_fulfillments_update_fulfillment_async.py index df22b660f6be..7191a0d10194 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_fulfillments_update_fulfillment_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_fulfillments_update_fulfillment_async.py @@ -53,4 +53,5 @@ async def sample_update_fulfillment(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Fulfillments_UpdateFulfillment_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_fulfillments_update_fulfillment_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_fulfillments_update_fulfillment_sync.py index e28fe4d01b0d..d5eacc3d3254 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_fulfillments_update_fulfillment_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_fulfillments_update_fulfillment_sync.py @@ -53,4 +53,5 @@ def sample_update_fulfillment(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Fulfillments_UpdateFulfillment_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_create_generator_evaluation_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_create_generator_evaluation_async.py new file mode 100644 index 000000000000..eb5b1897226f --- /dev/null +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_create_generator_evaluation_async.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateGeneratorEvaluation +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow + + +# [START dialogflow_v2beta1_generated_GeneratorEvaluations_CreateGeneratorEvaluation_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflow_v2beta1 + + +async def sample_create_generator_evaluation(): + # Create a client + client = dialogflow_v2beta1.GeneratorEvaluationsAsyncClient() + + # Initialize request argument(s) + generator_evaluation = dialogflow_v2beta1.GeneratorEvaluation() + generator_evaluation.generator_evaluation_config.input_data_config.input_data_source_type = ( + "INSIGHTS_CONVERSATIONS" + ) + generator_evaluation.generator_evaluation_config.output_gcs_bucket_path = ( + "output_gcs_bucket_path_value" + ) + generator_evaluation.initial_generator.published_model = "published_model_value" + + request = dialogflow_v2beta1.CreateGeneratorEvaluationRequest( + parent="parent_value", + generator_evaluation=generator_evaluation, + ) + + # Make the request + operation = client.create_generator_evaluation(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + +# [END dialogflow_v2beta1_generated_GeneratorEvaluations_CreateGeneratorEvaluation_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_create_generator_evaluation_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_create_generator_evaluation_sync.py new file mode 100644 index 000000000000..97f5abb99d2d --- /dev/null +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_create_generator_evaluation_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateGeneratorEvaluation +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow + + +# [START dialogflow_v2beta1_generated_GeneratorEvaluations_CreateGeneratorEvaluation_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflow_v2beta1 + + +def sample_create_generator_evaluation(): + # Create a client + client = dialogflow_v2beta1.GeneratorEvaluationsClient() + + # Initialize request argument(s) + generator_evaluation = dialogflow_v2beta1.GeneratorEvaluation() + generator_evaluation.generator_evaluation_config.input_data_config.input_data_source_type = ( + "INSIGHTS_CONVERSATIONS" + ) + generator_evaluation.generator_evaluation_config.output_gcs_bucket_path = ( + "output_gcs_bucket_path_value" + ) + generator_evaluation.initial_generator.published_model = "published_model_value" + + request = dialogflow_v2beta1.CreateGeneratorEvaluationRequest( + parent="parent_value", + generator_evaluation=generator_evaluation, + ) + + # Make the request + operation = client.create_generator_evaluation(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + +# [END dialogflow_v2beta1_generated_GeneratorEvaluations_CreateGeneratorEvaluation_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_delete_generator_evaluation_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_delete_generator_evaluation_async.py new file mode 100644 index 000000000000..d76bc9971783 --- /dev/null +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_delete_generator_evaluation_async.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteGeneratorEvaluation +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow + + +# [START dialogflow_v2beta1_generated_GeneratorEvaluations_DeleteGeneratorEvaluation_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflow_v2beta1 + + +async def sample_delete_generator_evaluation(): + # Create a client + client = dialogflow_v2beta1.GeneratorEvaluationsAsyncClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.DeleteGeneratorEvaluationRequest( + name="name_value", + ) + + # Make the request + await client.delete_generator_evaluation(request=request) + + +# [END dialogflow_v2beta1_generated_GeneratorEvaluations_DeleteGeneratorEvaluation_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_delete_generator_evaluation_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_delete_generator_evaluation_sync.py new file mode 100644 index 000000000000..cd96bc443b39 --- /dev/null +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_delete_generator_evaluation_sync.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteGeneratorEvaluation +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow + + +# [START dialogflow_v2beta1_generated_GeneratorEvaluations_DeleteGeneratorEvaluation_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflow_v2beta1 + + +def sample_delete_generator_evaluation(): + # Create a client + client = dialogflow_v2beta1.GeneratorEvaluationsClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.DeleteGeneratorEvaluationRequest( + name="name_value", + ) + + # Make the request + client.delete_generator_evaluation(request=request) + + +# [END dialogflow_v2beta1_generated_GeneratorEvaluations_DeleteGeneratorEvaluation_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_get_generator_evaluation_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_get_generator_evaluation_async.py new file mode 100644 index 000000000000..182dcf43619b --- /dev/null +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_get_generator_evaluation_async.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetGeneratorEvaluation +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow + + +# [START dialogflow_v2beta1_generated_GeneratorEvaluations_GetGeneratorEvaluation_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflow_v2beta1 + + +async def sample_get_generator_evaluation(): + # Create a client + client = dialogflow_v2beta1.GeneratorEvaluationsAsyncClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.GetGeneratorEvaluationRequest( + name="name_value", + ) + + # Make the request + response = await client.get_generator_evaluation(request=request) + + # Handle the response + print(response) + + +# [END dialogflow_v2beta1_generated_GeneratorEvaluations_GetGeneratorEvaluation_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_get_generator_evaluation_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_get_generator_evaluation_sync.py new file mode 100644 index 000000000000..c84da40c2353 --- /dev/null +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_get_generator_evaluation_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetGeneratorEvaluation +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow + + +# [START dialogflow_v2beta1_generated_GeneratorEvaluations_GetGeneratorEvaluation_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflow_v2beta1 + + +def sample_get_generator_evaluation(): + # Create a client + client = dialogflow_v2beta1.GeneratorEvaluationsClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.GetGeneratorEvaluationRequest( + name="name_value", + ) + + # Make the request + response = client.get_generator_evaluation(request=request) + + # Handle the response + print(response) + + +# [END dialogflow_v2beta1_generated_GeneratorEvaluations_GetGeneratorEvaluation_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_list_generator_evaluations_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_list_generator_evaluations_async.py new file mode 100644 index 000000000000..2d5d3ed82976 --- /dev/null +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_list_generator_evaluations_async.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListGeneratorEvaluations +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow + + +# [START dialogflow_v2beta1_generated_GeneratorEvaluations_ListGeneratorEvaluations_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflow_v2beta1 + + +async def sample_list_generator_evaluations(): + # Create a client + client = dialogflow_v2beta1.GeneratorEvaluationsAsyncClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.ListGeneratorEvaluationsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_generator_evaluations(request=request) + + # Handle the response + async for response in page_result: + print(response) + + +# [END dialogflow_v2beta1_generated_GeneratorEvaluations_ListGeneratorEvaluations_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_list_generator_evaluations_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_list_generator_evaluations_sync.py new file mode 100644 index 000000000000..f81466309b1d --- /dev/null +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generator_evaluations_list_generator_evaluations_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListGeneratorEvaluations +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow + + +# [START dialogflow_v2beta1_generated_GeneratorEvaluations_ListGeneratorEvaluations_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflow_v2beta1 + + +def sample_list_generator_evaluations(): + # Create a client + client = dialogflow_v2beta1.GeneratorEvaluationsClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.ListGeneratorEvaluationsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_generator_evaluations(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END dialogflow_v2beta1_generated_GeneratorEvaluations_ListGeneratorEvaluations_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_create_generator_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_create_generator_async.py index 5da99b9090dc..4cc5e49c767c 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_create_generator_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_create_generator_async.py @@ -53,4 +53,5 @@ async def sample_create_generator(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Generators_CreateGenerator_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_create_generator_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_create_generator_sync.py index 3d99f84ffafa..e6c43414a0a1 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_create_generator_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_create_generator_sync.py @@ -53,4 +53,5 @@ def sample_create_generator(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Generators_CreateGenerator_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_get_generator_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_get_generator_async.py index 37dca967cd94..d8338fd77393 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_get_generator_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_get_generator_async.py @@ -49,4 +49,5 @@ async def sample_get_generator(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Generators_GetGenerator_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_get_generator_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_get_generator_sync.py index a5621df066cd..2dc19a8a5fc8 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_get_generator_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_get_generator_sync.py @@ -49,4 +49,5 @@ def sample_get_generator(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Generators_GetGenerator_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_list_generators_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_list_generators_async.py index 2a98a8e7a706..47930f2f9c48 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_list_generators_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_list_generators_async.py @@ -50,4 +50,5 @@ async def sample_list_generators(): async for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Generators_ListGenerators_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_list_generators_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_list_generators_sync.py index 5c1c8cf46423..eb74f7dc25b9 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_list_generators_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_list_generators_sync.py @@ -50,4 +50,5 @@ def sample_list_generators(): for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Generators_ListGenerators_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_update_generator_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_update_generator_async.py index 475f8c611972..f98c385b0d88 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_update_generator_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_update_generator_async.py @@ -52,4 +52,5 @@ async def sample_update_generator(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Generators_UpdateGenerator_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_update_generator_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_update_generator_sync.py index c1409f2ab6b6..976467cfd46d 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_update_generator_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_generators_update_generator_sync.py @@ -52,4 +52,5 @@ def sample_update_generator(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Generators_UpdateGenerator_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_batch_delete_intents_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_batch_delete_intents_async.py index 4e44bb1af20c..698585790476 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_batch_delete_intents_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_batch_delete_intents_async.py @@ -57,4 +57,5 @@ async def sample_batch_delete_intents(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Intents_BatchDeleteIntents_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_batch_delete_intents_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_batch_delete_intents_sync.py index 86f10a5365f4..dbfdcac8c5c7 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_batch_delete_intents_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_batch_delete_intents_sync.py @@ -57,4 +57,5 @@ def sample_batch_delete_intents(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Intents_BatchDeleteIntents_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_batch_update_intents_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_batch_update_intents_async.py index c08347c0326b..27962a3076ca 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_batch_update_intents_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_batch_update_intents_async.py @@ -54,4 +54,5 @@ async def sample_batch_update_intents(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Intents_BatchUpdateIntents_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_batch_update_intents_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_batch_update_intents_sync.py index e8ed707876ef..5f0ebe552651 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_batch_update_intents_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_batch_update_intents_sync.py @@ -54,4 +54,5 @@ def sample_batch_update_intents(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Intents_BatchUpdateIntents_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_create_intent_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_create_intent_async.py index 14374f785bc1..289bbd87137d 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_create_intent_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_create_intent_async.py @@ -53,4 +53,5 @@ async def sample_create_intent(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Intents_CreateIntent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_create_intent_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_create_intent_sync.py index 442176e04f56..a9e4bad8d19f 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_create_intent_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_create_intent_sync.py @@ -53,4 +53,5 @@ def sample_create_intent(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Intents_CreateIntent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_get_intent_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_get_intent_async.py index 7f4bf9452ad2..fba1ae1fbeb9 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_get_intent_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_get_intent_async.py @@ -49,4 +49,5 @@ async def sample_get_intent(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Intents_GetIntent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_get_intent_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_get_intent_sync.py index 33f253bc227d..3b2b3e23ac14 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_get_intent_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_get_intent_sync.py @@ -49,4 +49,5 @@ def sample_get_intent(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Intents_GetIntent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_list_intents_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_list_intents_async.py index c2eff4d627c3..0070c2fec25c 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_list_intents_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_list_intents_async.py @@ -50,4 +50,5 @@ async def sample_list_intents(): async for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Intents_ListIntents_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_list_intents_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_list_intents_sync.py index dfbb044395f1..9672c300b246 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_list_intents_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_list_intents_sync.py @@ -50,4 +50,5 @@ def sample_list_intents(): for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Intents_ListIntents_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_update_intent_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_update_intent_async.py index 315dd4bcc698..5ef043804422 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_update_intent_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_update_intent_async.py @@ -52,4 +52,5 @@ async def sample_update_intent(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Intents_UpdateIntent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_update_intent_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_update_intent_sync.py index a17554efd3b9..e99eddc5ddfe 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_update_intent_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_intents_update_intent_sync.py @@ -52,4 +52,5 @@ def sample_update_intent(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Intents_UpdateIntent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_create_knowledge_base_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_create_knowledge_base_async.py index 47d04da1463b..0ccda9af78b1 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_create_knowledge_base_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_create_knowledge_base_async.py @@ -53,4 +53,5 @@ async def sample_create_knowledge_base(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_KnowledgeBases_CreateKnowledgeBase_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_create_knowledge_base_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_create_knowledge_base_sync.py index 8edfc47555ca..bc218fe7cc36 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_create_knowledge_base_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_create_knowledge_base_sync.py @@ -53,4 +53,5 @@ def sample_create_knowledge_base(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_KnowledgeBases_CreateKnowledgeBase_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_get_knowledge_base_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_get_knowledge_base_async.py index c5f9709227f2..edbe6c137682 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_get_knowledge_base_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_get_knowledge_base_async.py @@ -49,4 +49,5 @@ async def sample_get_knowledge_base(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_KnowledgeBases_GetKnowledgeBase_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_get_knowledge_base_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_get_knowledge_base_sync.py index 855e5250a5d0..1696fbffdbaf 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_get_knowledge_base_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_get_knowledge_base_sync.py @@ -49,4 +49,5 @@ def sample_get_knowledge_base(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_KnowledgeBases_GetKnowledgeBase_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_list_knowledge_bases_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_list_knowledge_bases_async.py index dc2d37fc2768..ff88eec4a9c3 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_list_knowledge_bases_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_list_knowledge_bases_async.py @@ -50,4 +50,5 @@ async def sample_list_knowledge_bases(): async for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_KnowledgeBases_ListKnowledgeBases_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_list_knowledge_bases_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_list_knowledge_bases_sync.py index 28a9248f78f3..6ebf6bd6967b 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_list_knowledge_bases_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_list_knowledge_bases_sync.py @@ -50,4 +50,5 @@ def sample_list_knowledge_bases(): for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_KnowledgeBases_ListKnowledgeBases_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_update_knowledge_base_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_update_knowledge_base_async.py index b8b38bc18d4d..af7dbb02b2f4 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_update_knowledge_base_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_update_knowledge_base_async.py @@ -52,4 +52,5 @@ async def sample_update_knowledge_base(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_KnowledgeBases_UpdateKnowledgeBase_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_update_knowledge_base_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_update_knowledge_base_sync.py index 009ee75d7453..361a5e425ebe 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_update_knowledge_base_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_knowledge_bases_update_knowledge_base_sync.py @@ -52,4 +52,5 @@ def sample_update_knowledge_base(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_KnowledgeBases_UpdateKnowledgeBase_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_analyze_content_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_analyze_content_async.py index 8576edeeee37..f29fc98a44cf 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_analyze_content_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_analyze_content_async.py @@ -49,4 +49,5 @@ async def sample_analyze_content(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Participants_AnalyzeContent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_analyze_content_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_analyze_content_sync.py index 118b28b68a81..e2662e06cf8a 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_analyze_content_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_analyze_content_sync.py @@ -49,4 +49,5 @@ def sample_analyze_content(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Participants_AnalyzeContent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_bidi_streaming_analyze_content_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_bidi_streaming_analyze_content_async.py new file mode 100644 index 000000000000..027e20abb814 --- /dev/null +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_bidi_streaming_analyze_content_async.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BidiStreamingAnalyzeContent +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow + + +# [START dialogflow_v2beta1_generated_Participants_BidiStreamingAnalyzeContent_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflow_v2beta1 + + +async def sample_bidi_streaming_analyze_content(): + # Create a client + client = dialogflow_v2beta1.ParticipantsAsyncClient() + + # Initialize request argument(s) + config = dialogflow_v2beta1.Config() + config.voice_session_config.input_audio_encoding = "AUDIO_ENCODING_ALAW" + config.voice_session_config.input_audio_sample_rate_hertz = 3097 + config.voice_session_config.output_audio_encoding = "OUTPUT_AUDIO_ENCODING_ALAW" + config.voice_session_config.output_audio_sample_rate_hertz = 3226 + config.participant = "participant_value" + + request = dialogflow_v2beta1.BidiStreamingAnalyzeContentRequest( + config=config, + ) + + # This method expects an iterator which contains + # 'dialogflow_v2beta1.BidiStreamingAnalyzeContentRequest' objects + # Here we create a generator that yields a single `request` for + # demonstrative purposes. + requests = [request] + + def request_generator(): + for request in requests: + yield request + + # Make the request + stream = await client.bidi_streaming_analyze_content(requests=request_generator()) + + # Handle the response + async for response in stream: + print(response) + + +# [END dialogflow_v2beta1_generated_Participants_BidiStreamingAnalyzeContent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_bidi_streaming_analyze_content_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_bidi_streaming_analyze_content_sync.py new file mode 100644 index 000000000000..2436866faa1f --- /dev/null +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_bidi_streaming_analyze_content_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for BidiStreamingAnalyzeContent +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow + + +# [START dialogflow_v2beta1_generated_Participants_BidiStreamingAnalyzeContent_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflow_v2beta1 + + +def sample_bidi_streaming_analyze_content(): + # Create a client + client = dialogflow_v2beta1.ParticipantsClient() + + # Initialize request argument(s) + config = dialogflow_v2beta1.Config() + config.voice_session_config.input_audio_encoding = "AUDIO_ENCODING_ALAW" + config.voice_session_config.input_audio_sample_rate_hertz = 3097 + config.voice_session_config.output_audio_encoding = "OUTPUT_AUDIO_ENCODING_ALAW" + config.voice_session_config.output_audio_sample_rate_hertz = 3226 + config.participant = "participant_value" + + request = dialogflow_v2beta1.BidiStreamingAnalyzeContentRequest( + config=config, + ) + + # This method expects an iterator which contains + # 'dialogflow_v2beta1.BidiStreamingAnalyzeContentRequest' objects + # Here we create a generator that yields a single `request` for + # demonstrative purposes. + requests = [request] + + def request_generator(): + for request in requests: + yield request + + # Make the request + stream = client.bidi_streaming_analyze_content(requests=request_generator()) + + # Handle the response + for response in stream: + print(response) + + +# [END dialogflow_v2beta1_generated_Participants_BidiStreamingAnalyzeContent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_compile_suggestion_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_compile_suggestion_async.py index 511b388e3c28..ae7f27e029a5 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_compile_suggestion_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_compile_suggestion_async.py @@ -39,8 +39,7 @@ async def sample_compile_suggestion(): client = dialogflow_v2beta1.ParticipantsAsyncClient() # Initialize request argument(s) - request = dialogflow_v2beta1.CompileSuggestionRequest( - ) + request = dialogflow_v2beta1.CompileSuggestionRequest() # Make the request response = await client.compile_suggestion(request=request) @@ -48,4 +47,5 @@ async def sample_compile_suggestion(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Participants_CompileSuggestion_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_compile_suggestion_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_compile_suggestion_sync.py index c5428da54c1e..c76438124fd7 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_compile_suggestion_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_compile_suggestion_sync.py @@ -39,8 +39,7 @@ def sample_compile_suggestion(): client = dialogflow_v2beta1.ParticipantsClient() # Initialize request argument(s) - request = dialogflow_v2beta1.CompileSuggestionRequest( - ) + request = dialogflow_v2beta1.CompileSuggestionRequest() # Make the request response = client.compile_suggestion(request=request) @@ -48,4 +47,5 @@ def sample_compile_suggestion(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Participants_CompileSuggestion_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_create_participant_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_create_participant_async.py index d57881d63ce0..ca2291e62755 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_create_participant_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_create_participant_async.py @@ -49,4 +49,5 @@ async def sample_create_participant(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Participants_CreateParticipant_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_create_participant_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_create_participant_sync.py index e47b3f4d1eeb..663ca84eaba8 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_create_participant_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_create_participant_sync.py @@ -49,4 +49,5 @@ def sample_create_participant(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Participants_CreateParticipant_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_get_participant_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_get_participant_async.py index df1a88fa153d..fc1eb24696d6 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_get_participant_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_get_participant_async.py @@ -49,4 +49,5 @@ async def sample_get_participant(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Participants_GetParticipant_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_get_participant_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_get_participant_sync.py index 2ce4dc341a55..b6a175fc7700 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_get_participant_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_get_participant_sync.py @@ -49,4 +49,5 @@ def sample_get_participant(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Participants_GetParticipant_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_list_participants_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_list_participants_async.py index 9d4f4a2bced7..6d58303a5329 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_list_participants_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_list_participants_async.py @@ -50,4 +50,5 @@ async def sample_list_participants(): async for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Participants_ListParticipants_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_list_participants_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_list_participants_sync.py index c2d36898e728..63bf916b24e4 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_list_participants_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_list_participants_sync.py @@ -50,4 +50,5 @@ def sample_list_participants(): for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Participants_ListParticipants_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_list_suggestions_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_list_suggestions_async.py index e1ee73b1a23b..60ead1a7a005 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_list_suggestions_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_list_suggestions_async.py @@ -39,8 +39,7 @@ async def sample_list_suggestions(): client = dialogflow_v2beta1.ParticipantsAsyncClient() # Initialize request argument(s) - request = dialogflow_v2beta1.ListSuggestionsRequest( - ) + request = dialogflow_v2beta1.ListSuggestionsRequest() # Make the request page_result = client.list_suggestions(request=request) @@ -49,4 +48,5 @@ async def sample_list_suggestions(): async for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Participants_ListSuggestions_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_list_suggestions_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_list_suggestions_sync.py index 7c96ee9e7c8e..6bff9f82f0cd 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_list_suggestions_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_list_suggestions_sync.py @@ -39,8 +39,7 @@ def sample_list_suggestions(): client = dialogflow_v2beta1.ParticipantsClient() # Initialize request argument(s) - request = dialogflow_v2beta1.ListSuggestionsRequest( - ) + request = dialogflow_v2beta1.ListSuggestionsRequest() # Make the request page_result = client.list_suggestions(request=request) @@ -49,4 +48,5 @@ def sample_list_suggestions(): for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Participants_ListSuggestions_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_streaming_analyze_content_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_streaming_analyze_content_async.py index 60d26b6a4b28..f21aa62cb04f 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_streaming_analyze_content_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_streaming_analyze_content_async.py @@ -46,7 +46,7 @@ async def sample_streaming_analyze_content(): request = dialogflow_v2beta1.StreamingAnalyzeContentRequest( audio_config=audio_config, - input_audio=b'input_audio_blob', + input_audio=b"input_audio_blob", participant="participant_value", ) @@ -67,4 +67,5 @@ def request_generator(): async for response in stream: print(response) + # [END dialogflow_v2beta1_generated_Participants_StreamingAnalyzeContent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_streaming_analyze_content_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_streaming_analyze_content_sync.py index ef3e09b2d957..5c03eb5177d4 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_streaming_analyze_content_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_streaming_analyze_content_sync.py @@ -46,7 +46,7 @@ def sample_streaming_analyze_content(): request = dialogflow_v2beta1.StreamingAnalyzeContentRequest( audio_config=audio_config, - input_audio=b'input_audio_blob', + input_audio=b"input_audio_blob", participant="participant_value", ) @@ -67,4 +67,5 @@ def request_generator(): for response in stream: print(response) + # [END dialogflow_v2beta1_generated_Participants_StreamingAnalyzeContent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_articles_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_articles_async.py index bec1e7969ba6..c291dc20de2f 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_articles_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_articles_async.py @@ -49,4 +49,5 @@ async def sample_suggest_articles(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Participants_SuggestArticles_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_articles_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_articles_sync.py index ba510f14990a..b8af0c61f37c 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_articles_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_articles_sync.py @@ -49,4 +49,5 @@ def sample_suggest_articles(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Participants_SuggestArticles_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_faq_answers_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_faq_answers_async.py index bbe767db6e0c..992b7d95fd1c 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_faq_answers_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_faq_answers_async.py @@ -49,4 +49,5 @@ async def sample_suggest_faq_answers(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Participants_SuggestFaqAnswers_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_faq_answers_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_faq_answers_sync.py index f6aad27e4dc0..4be2e5e651d0 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_faq_answers_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_faq_answers_sync.py @@ -49,4 +49,5 @@ def sample_suggest_faq_answers(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Participants_SuggestFaqAnswers_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_knowledge_assist_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_knowledge_assist_async.py index ed82a9a48b1e..794a557d9306 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_knowledge_assist_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_knowledge_assist_async.py @@ -49,4 +49,5 @@ async def sample_suggest_knowledge_assist(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Participants_SuggestKnowledgeAssist_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_knowledge_assist_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_knowledge_assist_sync.py index de544393d23e..989534ee0828 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_knowledge_assist_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_knowledge_assist_sync.py @@ -49,4 +49,5 @@ def sample_suggest_knowledge_assist(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Participants_SuggestKnowledgeAssist_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_smart_replies_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_smart_replies_async.py index a7ffbda3c5aa..317e26218bb0 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_smart_replies_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_smart_replies_async.py @@ -49,4 +49,5 @@ async def sample_suggest_smart_replies(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Participants_SuggestSmartReplies_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_smart_replies_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_smart_replies_sync.py index 689c812b6121..f8d8e0d1e3ed 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_smart_replies_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_suggest_smart_replies_sync.py @@ -49,4 +49,5 @@ def sample_suggest_smart_replies(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Participants_SuggestSmartReplies_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_update_participant_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_update_participant_async.py index fefa497961b9..d786515efb94 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_update_participant_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_update_participant_async.py @@ -39,8 +39,7 @@ async def sample_update_participant(): client = dialogflow_v2beta1.ParticipantsAsyncClient() # Initialize request argument(s) - request = dialogflow_v2beta1.UpdateParticipantRequest( - ) + request = dialogflow_v2beta1.UpdateParticipantRequest() # Make the request response = await client.update_participant(request=request) @@ -48,4 +47,5 @@ async def sample_update_participant(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Participants_UpdateParticipant_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_update_participant_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_update_participant_sync.py index c6d16f84725b..a21d00639de3 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_update_participant_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_participants_update_participant_sync.py @@ -39,8 +39,7 @@ def sample_update_participant(): client = dialogflow_v2beta1.ParticipantsClient() # Initialize request argument(s) - request = dialogflow_v2beta1.UpdateParticipantRequest( - ) + request = dialogflow_v2beta1.UpdateParticipantRequest() # Make the request response = client.update_participant(request=request) @@ -48,4 +47,5 @@ def sample_update_participant(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Participants_UpdateParticipant_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_delete_phone_number_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_delete_phone_number_async.py index 81046498427a..c3ab8899ae8a 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_delete_phone_number_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_delete_phone_number_async.py @@ -49,4 +49,5 @@ async def sample_delete_phone_number(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_PhoneNumbers_DeletePhoneNumber_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_delete_phone_number_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_delete_phone_number_sync.py index eaa3cbaabf1f..7a312be522bf 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_delete_phone_number_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_delete_phone_number_sync.py @@ -49,4 +49,5 @@ def sample_delete_phone_number(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_PhoneNumbers_DeletePhoneNumber_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_list_phone_numbers_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_list_phone_numbers_async.py index 20e9f929753e..c3ba2b559b92 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_list_phone_numbers_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_list_phone_numbers_async.py @@ -50,4 +50,5 @@ async def sample_list_phone_numbers(): async for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_PhoneNumbers_ListPhoneNumbers_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_list_phone_numbers_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_list_phone_numbers_sync.py index e4d40ddcf346..2f0d79fcf9e5 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_list_phone_numbers_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_list_phone_numbers_sync.py @@ -50,4 +50,5 @@ def sample_list_phone_numbers(): for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_PhoneNumbers_ListPhoneNumbers_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_undelete_phone_number_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_undelete_phone_number_async.py index 4477b73bc5f6..beb3d8713504 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_undelete_phone_number_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_undelete_phone_number_async.py @@ -49,4 +49,5 @@ async def sample_undelete_phone_number(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_PhoneNumbers_UndeletePhoneNumber_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_undelete_phone_number_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_undelete_phone_number_sync.py index 39ed7ac97567..5ac13eb36061 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_undelete_phone_number_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_undelete_phone_number_sync.py @@ -49,4 +49,5 @@ def sample_undelete_phone_number(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_PhoneNumbers_UndeletePhoneNumber_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_update_phone_number_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_update_phone_number_async.py index b2d2021cfc2c..78408262fe25 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_update_phone_number_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_update_phone_number_async.py @@ -39,8 +39,7 @@ async def sample_update_phone_number(): client = dialogflow_v2beta1.PhoneNumbersAsyncClient() # Initialize request argument(s) - request = dialogflow_v2beta1.UpdatePhoneNumberRequest( - ) + request = dialogflow_v2beta1.UpdatePhoneNumberRequest() # Make the request response = await client.update_phone_number(request=request) @@ -48,4 +47,5 @@ async def sample_update_phone_number(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_PhoneNumbers_UpdatePhoneNumber_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_update_phone_number_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_update_phone_number_sync.py index 608b20b62aba..f0d3eb055083 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_update_phone_number_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_phone_numbers_update_phone_number_sync.py @@ -39,8 +39,7 @@ def sample_update_phone_number(): client = dialogflow_v2beta1.PhoneNumbersClient() # Initialize request argument(s) - request = dialogflow_v2beta1.UpdatePhoneNumberRequest( - ) + request = dialogflow_v2beta1.UpdatePhoneNumberRequest() # Make the request response = client.update_phone_number(request=request) @@ -48,4 +47,5 @@ def sample_update_phone_number(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_PhoneNumbers_UpdatePhoneNumber_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_create_session_entity_type_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_create_session_entity_type_async.py index 86f6ac0f804d..71deeef50853 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_create_session_entity_type_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_create_session_entity_type_async.py @@ -49,4 +49,5 @@ async def sample_create_session_entity_type(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_SessionEntityTypes_CreateSessionEntityType_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_create_session_entity_type_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_create_session_entity_type_sync.py index 92f328a6f8be..15a6e8761920 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_create_session_entity_type_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_create_session_entity_type_sync.py @@ -49,4 +49,5 @@ def sample_create_session_entity_type(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_SessionEntityTypes_CreateSessionEntityType_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_get_session_entity_type_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_get_session_entity_type_async.py index d30dda293281..c059567471ca 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_get_session_entity_type_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_get_session_entity_type_async.py @@ -49,4 +49,5 @@ async def sample_get_session_entity_type(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_SessionEntityTypes_GetSessionEntityType_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_get_session_entity_type_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_get_session_entity_type_sync.py index 242c81ccaa43..6ced38139b2a 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_get_session_entity_type_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_get_session_entity_type_sync.py @@ -49,4 +49,5 @@ def sample_get_session_entity_type(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_SessionEntityTypes_GetSessionEntityType_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_list_session_entity_types_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_list_session_entity_types_async.py index 88fcbbade3bb..eb9909b553be 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_list_session_entity_types_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_list_session_entity_types_async.py @@ -50,4 +50,5 @@ async def sample_list_session_entity_types(): async for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_SessionEntityTypes_ListSessionEntityTypes_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_list_session_entity_types_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_list_session_entity_types_sync.py index e5cd8574129d..b86e4c59987e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_list_session_entity_types_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_list_session_entity_types_sync.py @@ -50,4 +50,5 @@ def sample_list_session_entity_types(): for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_SessionEntityTypes_ListSessionEntityTypes_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_update_session_entity_type_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_update_session_entity_type_async.py index 0e6233aa18c7..33094a881c1f 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_update_session_entity_type_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_update_session_entity_type_async.py @@ -39,8 +39,7 @@ async def sample_update_session_entity_type(): client = dialogflow_v2beta1.SessionEntityTypesAsyncClient() # Initialize request argument(s) - request = dialogflow_v2beta1.UpdateSessionEntityTypeRequest( - ) + request = dialogflow_v2beta1.UpdateSessionEntityTypeRequest() # Make the request response = await client.update_session_entity_type(request=request) @@ -48,4 +47,5 @@ async def sample_update_session_entity_type(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_SessionEntityTypes_UpdateSessionEntityType_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_update_session_entity_type_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_update_session_entity_type_sync.py index b62931df047d..1875982efcca 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_update_session_entity_type_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_session_entity_types_update_session_entity_type_sync.py @@ -39,8 +39,7 @@ def sample_update_session_entity_type(): client = dialogflow_v2beta1.SessionEntityTypesClient() # Initialize request argument(s) - request = dialogflow_v2beta1.UpdateSessionEntityTypeRequest( - ) + request = dialogflow_v2beta1.UpdateSessionEntityTypeRequest() # Make the request response = client.update_session_entity_type(request=request) @@ -48,4 +47,5 @@ def sample_update_session_entity_type(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_SessionEntityTypes_UpdateSessionEntityType_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sessions_detect_intent_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sessions_detect_intent_async.py index c1aca6ba77f0..f31bb41497eb 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sessions_detect_intent_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sessions_detect_intent_async.py @@ -55,4 +55,5 @@ async def sample_detect_intent(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Sessions_DetectIntent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sessions_detect_intent_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sessions_detect_intent_sync.py index 155dbb9c4b31..2191187efd1f 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sessions_detect_intent_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sessions_detect_intent_sync.py @@ -55,4 +55,5 @@ def sample_detect_intent(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Sessions_DetectIntent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sessions_streaming_detect_intent_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sessions_streaming_detect_intent_async.py index 035f6523234d..97c3ca6b6964 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sessions_streaming_detect_intent_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sessions_streaming_detect_intent_async.py @@ -66,4 +66,5 @@ def request_generator(): async for response in stream: print(response) + # [END dialogflow_v2beta1_generated_Sessions_StreamingDetectIntent_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sessions_streaming_detect_intent_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sessions_streaming_detect_intent_sync.py index 377700c00d64..f2800875391b 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sessions_streaming_detect_intent_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sessions_streaming_detect_intent_sync.py @@ -66,4 +66,5 @@ def request_generator(): for response in stream: print(response) + # [END dialogflow_v2beta1_generated_Sessions_StreamingDetectIntent_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_create_sip_trunk_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_create_sip_trunk_async.py index 960840ecfeed..9b93dcc3115a 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_create_sip_trunk_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_create_sip_trunk_async.py @@ -40,7 +40,10 @@ async def sample_create_sip_trunk(): # Initialize request argument(s) sip_trunk = dialogflow_v2beta1.SipTrunk() - sip_trunk.expected_hostname = ['expected_hostname_value1', 'expected_hostname_value2'] + sip_trunk.expected_hostname = [ + "expected_hostname_value1", + "expected_hostname_value2", + ] request = dialogflow_v2beta1.CreateSipTrunkRequest( parent="parent_value", @@ -53,4 +56,5 @@ async def sample_create_sip_trunk(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_SipTrunks_CreateSipTrunk_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_create_sip_trunk_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_create_sip_trunk_sync.py index 9d3d39bf8707..b03065974c54 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_create_sip_trunk_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_create_sip_trunk_sync.py @@ -40,7 +40,10 @@ def sample_create_sip_trunk(): # Initialize request argument(s) sip_trunk = dialogflow_v2beta1.SipTrunk() - sip_trunk.expected_hostname = ['expected_hostname_value1', 'expected_hostname_value2'] + sip_trunk.expected_hostname = [ + "expected_hostname_value1", + "expected_hostname_value2", + ] request = dialogflow_v2beta1.CreateSipTrunkRequest( parent="parent_value", @@ -53,4 +56,5 @@ def sample_create_sip_trunk(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_SipTrunks_CreateSipTrunk_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_get_sip_trunk_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_get_sip_trunk_async.py index c69da5ad84e7..80207da7774a 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_get_sip_trunk_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_get_sip_trunk_async.py @@ -49,4 +49,5 @@ async def sample_get_sip_trunk(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_SipTrunks_GetSipTrunk_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_get_sip_trunk_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_get_sip_trunk_sync.py index 5c042d9aa7a5..041c9b3f5e87 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_get_sip_trunk_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_get_sip_trunk_sync.py @@ -49,4 +49,5 @@ def sample_get_sip_trunk(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_SipTrunks_GetSipTrunk_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_list_sip_trunks_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_list_sip_trunks_async.py index a1961b1c95e1..f12a639dd70c 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_list_sip_trunks_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_list_sip_trunks_async.py @@ -50,4 +50,5 @@ async def sample_list_sip_trunks(): async for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_SipTrunks_ListSipTrunks_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_list_sip_trunks_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_list_sip_trunks_sync.py index 4e1686ad140b..c25bfce61042 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_list_sip_trunks_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_list_sip_trunks_sync.py @@ -50,4 +50,5 @@ def sample_list_sip_trunks(): for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_SipTrunks_ListSipTrunks_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_update_sip_trunk_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_update_sip_trunk_async.py index dbb75c90e35b..f60605632c3f 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_update_sip_trunk_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_update_sip_trunk_async.py @@ -40,7 +40,10 @@ async def sample_update_sip_trunk(): # Initialize request argument(s) sip_trunk = dialogflow_v2beta1.SipTrunk() - sip_trunk.expected_hostname = ['expected_hostname_value1', 'expected_hostname_value2'] + sip_trunk.expected_hostname = [ + "expected_hostname_value1", + "expected_hostname_value2", + ] request = dialogflow_v2beta1.UpdateSipTrunkRequest( sip_trunk=sip_trunk, @@ -52,4 +55,5 @@ async def sample_update_sip_trunk(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_SipTrunks_UpdateSipTrunk_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_update_sip_trunk_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_update_sip_trunk_sync.py index ccc7eb90d579..a30cb5e3e6d6 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_update_sip_trunk_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_sip_trunks_update_sip_trunk_sync.py @@ -40,7 +40,10 @@ def sample_update_sip_trunk(): # Initialize request argument(s) sip_trunk = dialogflow_v2beta1.SipTrunk() - sip_trunk.expected_hostname = ['expected_hostname_value1', 'expected_hostname_value2'] + sip_trunk.expected_hostname = [ + "expected_hostname_value1", + "expected_hostname_value2", + ] request = dialogflow_v2beta1.UpdateSipTrunkRequest( sip_trunk=sip_trunk, @@ -52,4 +55,5 @@ def sample_update_sip_trunk(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_SipTrunks_UpdateSipTrunk_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_create_tool_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_create_tool_async.py new file mode 100644 index 000000000000..8f3e6368fab6 --- /dev/null +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_create_tool_async.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateTool +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow + + +# [START dialogflow_v2beta1_generated_Tools_CreateTool_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflow_v2beta1 + + +async def sample_create_tool(): + # Create a client + client = dialogflow_v2beta1.ToolsAsyncClient() + + # Initialize request argument(s) + tool = dialogflow_v2beta1.Tool() + tool.extension_spec.name = "name_value" + tool.tool_key = "tool_key_value" + + request = dialogflow_v2beta1.CreateToolRequest( + parent="parent_value", + tool=tool, + ) + + # Make the request + response = await client.create_tool(request=request) + + # Handle the response + print(response) + + +# [END dialogflow_v2beta1_generated_Tools_CreateTool_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_create_tool_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_create_tool_sync.py new file mode 100644 index 000000000000..9ad3de148223 --- /dev/null +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_create_tool_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for CreateTool +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow + + +# [START dialogflow_v2beta1_generated_Tools_CreateTool_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflow_v2beta1 + + +def sample_create_tool(): + # Create a client + client = dialogflow_v2beta1.ToolsClient() + + # Initialize request argument(s) + tool = dialogflow_v2beta1.Tool() + tool.extension_spec.name = "name_value" + tool.tool_key = "tool_key_value" + + request = dialogflow_v2beta1.CreateToolRequest( + parent="parent_value", + tool=tool, + ) + + # Make the request + response = client.create_tool(request=request) + + # Handle the response + print(response) + + +# [END dialogflow_v2beta1_generated_Tools_CreateTool_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_delete_tool_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_delete_tool_async.py new file mode 100644 index 000000000000..f0f96d1365c2 --- /dev/null +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_delete_tool_async.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteTool +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow + + +# [START dialogflow_v2beta1_generated_Tools_DeleteTool_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflow_v2beta1 + + +async def sample_delete_tool(): + # Create a client + client = dialogflow_v2beta1.ToolsAsyncClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.DeleteToolRequest( + name="name_value", + ) + + # Make the request + await client.delete_tool(request=request) + + +# [END dialogflow_v2beta1_generated_Tools_DeleteTool_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_delete_tool_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_delete_tool_sync.py new file mode 100644 index 000000000000..bc7f625d534b --- /dev/null +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_delete_tool_sync.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Generated code. DO NOT EDIT! +# +# Snippet for DeleteTool +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow + + +# [START dialogflow_v2beta1_generated_Tools_DeleteTool_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflow_v2beta1 + + +def sample_delete_tool(): + # Create a client + client = dialogflow_v2beta1.ToolsClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.DeleteToolRequest( + name="name_value", + ) + + # Make the request + client.delete_tool(request=request) + + +# [END dialogflow_v2beta1_generated_Tools_DeleteTool_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_get_tool_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_get_tool_async.py new file mode 100644 index 000000000000..d89f19601356 --- /dev/null +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_get_tool_async.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetTool +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow + + +# [START dialogflow_v2beta1_generated_Tools_GetTool_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflow_v2beta1 + + +async def sample_get_tool(): + # Create a client + client = dialogflow_v2beta1.ToolsAsyncClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.GetToolRequest( + name="name_value", + ) + + # Make the request + response = await client.get_tool(request=request) + + # Handle the response + print(response) + + +# [END dialogflow_v2beta1_generated_Tools_GetTool_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_get_tool_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_get_tool_sync.py new file mode 100644 index 000000000000..0d2502cd7c35 --- /dev/null +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_get_tool_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for GetTool +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow + + +# [START dialogflow_v2beta1_generated_Tools_GetTool_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflow_v2beta1 + + +def sample_get_tool(): + # Create a client + client = dialogflow_v2beta1.ToolsClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.GetToolRequest( + name="name_value", + ) + + # Make the request + response = client.get_tool(request=request) + + # Handle the response + print(response) + + +# [END dialogflow_v2beta1_generated_Tools_GetTool_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_list_tools_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_list_tools_async.py new file mode 100644 index 000000000000..5e38d66a3fd0 --- /dev/null +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_list_tools_async.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListTools +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow + + +# [START dialogflow_v2beta1_generated_Tools_ListTools_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflow_v2beta1 + + +async def sample_list_tools(): + # Create a client + client = dialogflow_v2beta1.ToolsAsyncClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.ListToolsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_tools(request=request) + + # Handle the response + async for response in page_result: + print(response) + + +# [END dialogflow_v2beta1_generated_Tools_ListTools_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_list_tools_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_list_tools_sync.py new file mode 100644 index 000000000000..4f6f6b6f5fa8 --- /dev/null +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_list_tools_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ListTools +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow + + +# [START dialogflow_v2beta1_generated_Tools_ListTools_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflow_v2beta1 + + +def sample_list_tools(): + # Create a client + client = dialogflow_v2beta1.ToolsClient() + + # Initialize request argument(s) + request = dialogflow_v2beta1.ListToolsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_tools(request=request) + + # Handle the response + for response in page_result: + print(response) + + +# [END dialogflow_v2beta1_generated_Tools_ListTools_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_update_tool_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_update_tool_async.py new file mode 100644 index 000000000000..e6903ae18834 --- /dev/null +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_update_tool_async.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateTool +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow + + +# [START dialogflow_v2beta1_generated_Tools_UpdateTool_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflow_v2beta1 + + +async def sample_update_tool(): + # Create a client + client = dialogflow_v2beta1.ToolsAsyncClient() + + # Initialize request argument(s) + tool = dialogflow_v2beta1.Tool() + tool.extension_spec.name = "name_value" + tool.tool_key = "tool_key_value" + + request = dialogflow_v2beta1.UpdateToolRequest( + tool=tool, + ) + + # Make the request + response = await client.update_tool(request=request) + + # Handle the response + print(response) + + +# [END dialogflow_v2beta1_generated_Tools_UpdateTool_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_update_tool_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_update_tool_sync.py new file mode 100644 index 000000000000..83f48ec77cb4 --- /dev/null +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_tools_update_tool_sync.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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for UpdateTool +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow + + +# [START dialogflow_v2beta1_generated_Tools_UpdateTool_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflow_v2beta1 + + +def sample_update_tool(): + # Create a client + client = dialogflow_v2beta1.ToolsClient() + + # Initialize request argument(s) + tool = dialogflow_v2beta1.Tool() + tool.extension_spec.name = "name_value" + tool.tool_key = "tool_key_value" + + request = dialogflow_v2beta1.UpdateToolRequest( + tool=tool, + ) + + # Make the request + response = client.update_tool(request=request) + + # Handle the response + print(response) + + +# [END dialogflow_v2beta1_generated_Tools_UpdateTool_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_create_version_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_create_version_async.py index 149fc65fadbb..1f25dcdbdeed 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_create_version_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_create_version_async.py @@ -49,4 +49,5 @@ async def sample_create_version(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Versions_CreateVersion_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_create_version_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_create_version_sync.py index 4ef2608e7aa1..e8d73d02482e 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_create_version_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_create_version_sync.py @@ -49,4 +49,5 @@ def sample_create_version(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Versions_CreateVersion_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_get_version_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_get_version_async.py index 9cc91f8c6650..c532aada711a 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_get_version_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_get_version_async.py @@ -49,4 +49,5 @@ async def sample_get_version(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Versions_GetVersion_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_get_version_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_get_version_sync.py index 09887930245e..b122ab1ba3de 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_get_version_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_get_version_sync.py @@ -49,4 +49,5 @@ def sample_get_version(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Versions_GetVersion_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_list_versions_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_list_versions_async.py index 02ecb9b2846a..0c61a451eb84 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_list_versions_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_list_versions_async.py @@ -50,4 +50,5 @@ async def sample_list_versions(): async for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Versions_ListVersions_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_list_versions_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_list_versions_sync.py index b4d1eed927af..d8cfff823517 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_list_versions_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_list_versions_sync.py @@ -50,4 +50,5 @@ def sample_list_versions(): for response in page_result: print(response) + # [END dialogflow_v2beta1_generated_Versions_ListVersions_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_update_version_async.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_update_version_async.py index 8c3fdebc75d3..8a58bab89488 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_update_version_async.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_update_version_async.py @@ -39,8 +39,7 @@ async def sample_update_version(): client = dialogflow_v2beta1.VersionsAsyncClient() # Initialize request argument(s) - request = dialogflow_v2beta1.UpdateVersionRequest( - ) + request = dialogflow_v2beta1.UpdateVersionRequest() # Make the request response = await client.update_version(request=request) @@ -48,4 +47,5 @@ async def sample_update_version(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Versions_UpdateVersion_async] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_update_version_sync.py b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_update_version_sync.py index ee16a11a698d..6c4e4c27bc92 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_update_version_sync.py +++ b/packages/google-cloud-dialogflow/samples/generated_samples/dialogflow_v2beta1_generated_versions_update_version_sync.py @@ -39,8 +39,7 @@ def sample_update_version(): client = dialogflow_v2beta1.VersionsClient() # Initialize request argument(s) - request = dialogflow_v2beta1.UpdateVersionRequest( - ) + request = dialogflow_v2beta1.UpdateVersionRequest() # Make the request response = client.update_version(request=request) @@ -48,4 +47,5 @@ def sample_update_version(): # Handle the response print(response) + # [END dialogflow_v2beta1_generated_Versions_UpdateVersion_sync] diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/snippet_metadata_google.cloud.dialogflow.v2beta1.json b/packages/google-cloud-dialogflow/samples/generated_samples/snippet_metadata_google.cloud.dialogflow.v2beta1.json index 33e0318ca519..201d3201a365 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/snippet_metadata_google.cloud.dialogflow.v2beta1.json +++ b/packages/google-cloud-dialogflow/samples/generated_samples/snippet_metadata_google.cloud.dialogflow.v2beta1.json @@ -10404,34 +10404,30 @@ "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsAsyncClient", - "shortName": "GeneratorsAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorEvaluationsAsyncClient", + "shortName": "GeneratorEvaluationsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsAsyncClient.create_generator", + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorEvaluationsAsyncClient.create_generator_evaluation", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Generators.CreateGenerator", + "fullName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations.CreateGeneratorEvaluation", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Generators", - "shortName": "Generators" + "fullName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "shortName": "GeneratorEvaluations" }, - "shortName": "CreateGenerator" + "shortName": "CreateGeneratorEvaluation" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.CreateGeneratorRequest" + "type": "google.cloud.dialogflow_v2beta1.types.CreateGeneratorEvaluationRequest" }, { "name": "parent", "type": "str" }, { - "name": "generator", - "type": "google.cloud.dialogflow_v2beta1.types.Generator" - }, - { - "name": "generator_id", - "type": "str" + "name": "generator_evaluation", + "type": "google.cloud.dialogflow_v2beta1.types.GeneratorEvaluation" }, { "name": "retry", @@ -10446,22 +10442,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.Generator", - "shortName": "create_generator" + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "create_generator_evaluation" }, - "description": "Sample for CreateGenerator", - "file": "dialogflow_v2beta1_generated_generators_create_generator_async.py", + "description": "Sample for CreateGeneratorEvaluation", + "file": "dialogflow_v2beta1_generated_generator_evaluations_create_generator_evaluation_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Generators_CreateGenerator_async", + "regionTag": "dialogflow_v2beta1_generated_GeneratorEvaluations_CreateGeneratorEvaluation_async", "segments": [ { - "end": 55, + "end": 61, "start": 27, "type": "FULL" }, { - "end": 55, + "end": 61, "start": 27, "type": "SHORT" }, @@ -10471,55 +10467,51 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 49, + "end": 51, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 52, - "start": 50, + "end": 58, + "start": 52, "type": "REQUEST_EXECUTION" }, { - "end": 56, - "start": 53, + "end": 62, + "start": 59, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_generators_create_generator_async.py" + "title": "dialogflow_v2beta1_generated_generator_evaluations_create_generator_evaluation_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsClient", - "shortName": "GeneratorsClient" + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorEvaluationsClient", + "shortName": "GeneratorEvaluationsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsClient.create_generator", + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorEvaluationsClient.create_generator_evaluation", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Generators.CreateGenerator", + "fullName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations.CreateGeneratorEvaluation", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Generators", - "shortName": "Generators" + "fullName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "shortName": "GeneratorEvaluations" }, - "shortName": "CreateGenerator" + "shortName": "CreateGeneratorEvaluation" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.CreateGeneratorRequest" + "type": "google.cloud.dialogflow_v2beta1.types.CreateGeneratorEvaluationRequest" }, { "name": "parent", "type": "str" }, { - "name": "generator", - "type": "google.cloud.dialogflow_v2beta1.types.Generator" - }, - { - "name": "generator_id", - "type": "str" + "name": "generator_evaluation", + "type": "google.cloud.dialogflow_v2beta1.types.GeneratorEvaluation" }, { "name": "retry", @@ -10534,22 +10526,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.Generator", - "shortName": "create_generator" + "resultType": "google.api_core.operation.Operation", + "shortName": "create_generator_evaluation" }, - "description": "Sample for CreateGenerator", - "file": "dialogflow_v2beta1_generated_generators_create_generator_sync.py", + "description": "Sample for CreateGeneratorEvaluation", + "file": "dialogflow_v2beta1_generated_generator_evaluations_create_generator_evaluation_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Generators_CreateGenerator_sync", + "regionTag": "dialogflow_v2beta1_generated_GeneratorEvaluations_CreateGeneratorEvaluation_sync", "segments": [ { - "end": 55, + "end": 61, "start": 27, "type": "FULL" }, { - "end": 55, + "end": 61, "start": 27, "type": "SHORT" }, @@ -10559,44 +10551,44 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 49, + "end": 51, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 52, - "start": 50, + "end": 58, + "start": 52, "type": "REQUEST_EXECUTION" }, { - "end": 56, - "start": 53, + "end": 62, + "start": 59, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_generators_create_generator_sync.py" + "title": "dialogflow_v2beta1_generated_generator_evaluations_create_generator_evaluation_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsAsyncClient", - "shortName": "GeneratorsAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorEvaluationsAsyncClient", + "shortName": "GeneratorEvaluationsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsAsyncClient.delete_generator", + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorEvaluationsAsyncClient.delete_generator_evaluation", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Generators.DeleteGenerator", + "fullName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations.DeleteGeneratorEvaluation", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Generators", - "shortName": "Generators" + "fullName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "shortName": "GeneratorEvaluations" }, - "shortName": "DeleteGenerator" + "shortName": "DeleteGeneratorEvaluation" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.DeleteGeneratorRequest" + "type": "google.cloud.dialogflow_v2beta1.types.DeleteGeneratorEvaluationRequest" }, { "name": "name", @@ -10615,13 +10607,13 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "shortName": "delete_generator" + "shortName": "delete_generator_evaluation" }, - "description": "Sample for DeleteGenerator", - "file": "dialogflow_v2beta1_generated_generators_delete_generator_async.py", + "description": "Sample for DeleteGeneratorEvaluation", + "file": "dialogflow_v2beta1_generated_generator_evaluations_delete_generator_evaluation_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Generators_DeleteGenerator_async", + "regionTag": "dialogflow_v2beta1_generated_GeneratorEvaluations_DeleteGeneratorEvaluation_async", "segments": [ { "end": 49, @@ -10652,28 +10644,28 @@ "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_generators_delete_generator_async.py" + "title": "dialogflow_v2beta1_generated_generator_evaluations_delete_generator_evaluation_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsClient", - "shortName": "GeneratorsClient" + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorEvaluationsClient", + "shortName": "GeneratorEvaluationsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsClient.delete_generator", + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorEvaluationsClient.delete_generator_evaluation", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Generators.DeleteGenerator", + "fullName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations.DeleteGeneratorEvaluation", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Generators", - "shortName": "Generators" + "fullName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "shortName": "GeneratorEvaluations" }, - "shortName": "DeleteGenerator" + "shortName": "DeleteGeneratorEvaluation" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.DeleteGeneratorRequest" + "type": "google.cloud.dialogflow_v2beta1.types.DeleteGeneratorEvaluationRequest" }, { "name": "name", @@ -10692,13 +10684,13 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "shortName": "delete_generator" + "shortName": "delete_generator_evaluation" }, - "description": "Sample for DeleteGenerator", - "file": "dialogflow_v2beta1_generated_generators_delete_generator_sync.py", + "description": "Sample for DeleteGeneratorEvaluation", + "file": "dialogflow_v2beta1_generated_generator_evaluations_delete_generator_evaluation_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Generators_DeleteGenerator_sync", + "regionTag": "dialogflow_v2beta1_generated_GeneratorEvaluations_DeleteGeneratorEvaluation_sync", "segments": [ { "end": 49, @@ -10729,29 +10721,29 @@ "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_generators_delete_generator_sync.py" + "title": "dialogflow_v2beta1_generated_generator_evaluations_delete_generator_evaluation_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsAsyncClient", - "shortName": "GeneratorsAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorEvaluationsAsyncClient", + "shortName": "GeneratorEvaluationsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsAsyncClient.get_generator", + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorEvaluationsAsyncClient.get_generator_evaluation", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Generators.GetGenerator", + "fullName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations.GetGeneratorEvaluation", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Generators", - "shortName": "Generators" + "fullName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "shortName": "GeneratorEvaluations" }, - "shortName": "GetGenerator" + "shortName": "GetGeneratorEvaluation" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.GetGeneratorRequest" + "type": "google.cloud.dialogflow_v2beta1.types.GetGeneratorEvaluationRequest" }, { "name": "name", @@ -10770,14 +10762,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.Generator", - "shortName": "get_generator" + "resultType": "google.cloud.dialogflow_v2beta1.types.GeneratorEvaluation", + "shortName": "get_generator_evaluation" }, - "description": "Sample for GetGenerator", - "file": "dialogflow_v2beta1_generated_generators_get_generator_async.py", + "description": "Sample for GetGeneratorEvaluation", + "file": "dialogflow_v2beta1_generated_generator_evaluations_get_generator_evaluation_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Generators_GetGenerator_async", + "regionTag": "dialogflow_v2beta1_generated_GeneratorEvaluations_GetGeneratorEvaluation_async", "segments": [ { "end": 51, @@ -10810,28 +10802,28 @@ "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_generators_get_generator_async.py" + "title": "dialogflow_v2beta1_generated_generator_evaluations_get_generator_evaluation_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsClient", - "shortName": "GeneratorsClient" + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorEvaluationsClient", + "shortName": "GeneratorEvaluationsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsClient.get_generator", + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorEvaluationsClient.get_generator_evaluation", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Generators.GetGenerator", + "fullName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations.GetGeneratorEvaluation", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Generators", - "shortName": "Generators" + "fullName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "shortName": "GeneratorEvaluations" }, - "shortName": "GetGenerator" + "shortName": "GetGeneratorEvaluation" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.GetGeneratorRequest" + "type": "google.cloud.dialogflow_v2beta1.types.GetGeneratorEvaluationRequest" }, { "name": "name", @@ -10850,14 +10842,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.Generator", - "shortName": "get_generator" + "resultType": "google.cloud.dialogflow_v2beta1.types.GeneratorEvaluation", + "shortName": "get_generator_evaluation" }, - "description": "Sample for GetGenerator", - "file": "dialogflow_v2beta1_generated_generators_get_generator_sync.py", + "description": "Sample for GetGeneratorEvaluation", + "file": "dialogflow_v2beta1_generated_generator_evaluations_get_generator_evaluation_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Generators_GetGenerator_sync", + "regionTag": "dialogflow_v2beta1_generated_GeneratorEvaluations_GetGeneratorEvaluation_sync", "segments": [ { "end": 51, @@ -10890,29 +10882,29 @@ "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_generators_get_generator_sync.py" + "title": "dialogflow_v2beta1_generated_generator_evaluations_get_generator_evaluation_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsAsyncClient", - "shortName": "GeneratorsAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorEvaluationsAsyncClient", + "shortName": "GeneratorEvaluationsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsAsyncClient.list_generators", + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorEvaluationsAsyncClient.list_generator_evaluations", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Generators.ListGenerators", + "fullName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations.ListGeneratorEvaluations", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Generators", - "shortName": "Generators" + "fullName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "shortName": "GeneratorEvaluations" }, - "shortName": "ListGenerators" + "shortName": "ListGeneratorEvaluations" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.ListGeneratorsRequest" + "type": "google.cloud.dialogflow_v2beta1.types.ListGeneratorEvaluationsRequest" }, { "name": "parent", @@ -10931,14 +10923,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.services.generators.pagers.ListGeneratorsAsyncPager", - "shortName": "list_generators" + "resultType": "google.cloud.dialogflow_v2beta1.services.generator_evaluations.pagers.ListGeneratorEvaluationsAsyncPager", + "shortName": "list_generator_evaluations" }, - "description": "Sample for ListGenerators", - "file": "dialogflow_v2beta1_generated_generators_list_generators_async.py", + "description": "Sample for ListGeneratorEvaluations", + "file": "dialogflow_v2beta1_generated_generator_evaluations_list_generator_evaluations_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Generators_ListGenerators_async", + "regionTag": "dialogflow_v2beta1_generated_GeneratorEvaluations_ListGeneratorEvaluations_async", "segments": [ { "end": 52, @@ -10971,28 +10963,28 @@ "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_generators_list_generators_async.py" + "title": "dialogflow_v2beta1_generated_generator_evaluations_list_generator_evaluations_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsClient", - "shortName": "GeneratorsClient" + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorEvaluationsClient", + "shortName": "GeneratorEvaluationsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsClient.list_generators", + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorEvaluationsClient.list_generator_evaluations", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Generators.ListGenerators", + "fullName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations.ListGeneratorEvaluations", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Generators", - "shortName": "Generators" + "fullName": "google.cloud.dialogflow.v2beta1.GeneratorEvaluations", + "shortName": "GeneratorEvaluations" }, - "shortName": "ListGenerators" + "shortName": "ListGeneratorEvaluations" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.ListGeneratorsRequest" + "type": "google.cloud.dialogflow_v2beta1.types.ListGeneratorEvaluationsRequest" }, { "name": "parent", @@ -11011,14 +11003,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.services.generators.pagers.ListGeneratorsPager", - "shortName": "list_generators" + "resultType": "google.cloud.dialogflow_v2beta1.services.generator_evaluations.pagers.ListGeneratorEvaluationsPager", + "shortName": "list_generator_evaluations" }, - "description": "Sample for ListGenerators", - "file": "dialogflow_v2beta1_generated_generators_list_generators_sync.py", + "description": "Sample for ListGeneratorEvaluations", + "file": "dialogflow_v2beta1_generated_generator_evaluations_list_generator_evaluations_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Generators_ListGenerators_sync", + "regionTag": "dialogflow_v2beta1_generated_GeneratorEvaluations_ListGeneratorEvaluations_sync", "segments": [ { "end": 52, @@ -11051,7 +11043,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_generators_list_generators_sync.py" + "title": "dialogflow_v2beta1_generated_generator_evaluations_list_generator_evaluations_sync.py" }, { "canonical": true, @@ -11061,27 +11053,31 @@ "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsAsyncClient", "shortName": "GeneratorsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsAsyncClient.update_generator", + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsAsyncClient.create_generator", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Generators.UpdateGenerator", + "fullName": "google.cloud.dialogflow.v2beta1.Generators.CreateGenerator", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Generators", "shortName": "Generators" }, - "shortName": "UpdateGenerator" + "shortName": "CreateGenerator" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.UpdateGeneratorRequest" + "type": "google.cloud.dialogflow_v2beta1.types.CreateGeneratorRequest" + }, + { + "name": "parent", + "type": "str" }, { "name": "generator", "type": "google.cloud.dialogflow_v2beta1.types.Generator" }, { - "name": "update_mask", - "type": "google.protobuf.field_mask_pb2.FieldMask" + "name": "generator_id", + "type": "str" }, { "name": "retry", @@ -11097,21 +11093,21 @@ } ], "resultType": "google.cloud.dialogflow_v2beta1.types.Generator", - "shortName": "update_generator" + "shortName": "create_generator" }, - "description": "Sample for UpdateGenerator", - "file": "dialogflow_v2beta1_generated_generators_update_generator_async.py", + "description": "Sample for CreateGenerator", + "file": "dialogflow_v2beta1_generated_generators_create_generator_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Generators_UpdateGenerator_async", + "regionTag": "dialogflow_v2beta1_generated_Generators_CreateGenerator_async", "segments": [ { - "end": 54, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 54, + "end": 55, "start": 27, "type": "SHORT" }, @@ -11121,22 +11117,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 48, + "end": 49, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 51, - "start": 49, + "end": 52, + "start": 50, "type": "REQUEST_EXECUTION" }, { - "end": 55, - "start": 52, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_generators_update_generator_async.py" + "title": "dialogflow_v2beta1_generated_generators_create_generator_async.py" }, { "canonical": true, @@ -11145,27 +11141,31 @@ "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsClient", "shortName": "GeneratorsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsClient.update_generator", + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsClient.create_generator", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Generators.UpdateGenerator", + "fullName": "google.cloud.dialogflow.v2beta1.Generators.CreateGenerator", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Generators", "shortName": "Generators" }, - "shortName": "UpdateGenerator" + "shortName": "CreateGenerator" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.UpdateGeneratorRequest" + "type": "google.cloud.dialogflow_v2beta1.types.CreateGeneratorRequest" + }, + { + "name": "parent", + "type": "str" }, { "name": "generator", "type": "google.cloud.dialogflow_v2beta1.types.Generator" }, { - "name": "update_mask", - "type": "google.protobuf.field_mask_pb2.FieldMask" + "name": "generator_id", + "type": "str" }, { "name": "retry", @@ -11181,21 +11181,21 @@ } ], "resultType": "google.cloud.dialogflow_v2beta1.types.Generator", - "shortName": "update_generator" + "shortName": "create_generator" }, - "description": "Sample for UpdateGenerator", - "file": "dialogflow_v2beta1_generated_generators_update_generator_sync.py", + "description": "Sample for CreateGenerator", + "file": "dialogflow_v2beta1_generated_generators_create_generator_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Generators_UpdateGenerator_sync", + "regionTag": "dialogflow_v2beta1_generated_Generators_CreateGenerator_sync", "segments": [ { - "end": 54, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 54, + "end": 55, "start": 27, "type": "SHORT" }, @@ -11205,53 +11205,49 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 48, + "end": 49, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 51, - "start": 49, + "end": 52, + "start": 50, "type": "REQUEST_EXECUTION" }, { - "end": 55, - "start": 52, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_generators_update_generator_sync.py" + "title": "dialogflow_v2beta1_generated_generators_create_generator_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient", - "shortName": "IntentsAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsAsyncClient", + "shortName": "GeneratorsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient.batch_delete_intents", + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsAsyncClient.delete_generator", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Intents.BatchDeleteIntents", + "fullName": "google.cloud.dialogflow.v2beta1.Generators.DeleteGenerator", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Intents", - "shortName": "Intents" + "fullName": "google.cloud.dialogflow.v2beta1.Generators", + "shortName": "Generators" }, - "shortName": "BatchDeleteIntents" + "shortName": "DeleteGenerator" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.BatchDeleteIntentsRequest" + "type": "google.cloud.dialogflow_v2beta1.types.DeleteGeneratorRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, - { - "name": "intents", - "type": "MutableSequence[google.cloud.dialogflow_v2beta1.types.Intent]" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -11265,22 +11261,21 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "batch_delete_intents" + "shortName": "delete_generator" }, - "description": "Sample for BatchDeleteIntents", - "file": "dialogflow_v2beta1_generated_intents_batch_delete_intents_async.py", + "description": "Sample for DeleteGenerator", + "file": "dialogflow_v2beta1_generated_generators_delete_generator_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Intents_BatchDeleteIntents_async", + "regionTag": "dialogflow_v2beta1_generated_Generators_DeleteGenerator_async", "segments": [ { - "end": 59, + "end": 49, "start": 27, "type": "FULL" }, { - "end": 59, + "end": 49, "start": 27, "type": "SHORT" }, @@ -11290,52 +11285,46 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 49, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 56, - "start": 50, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 60, - "start": 57, + "end": 50, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_intents_batch_delete_intents_async.py" + "title": "dialogflow_v2beta1_generated_generators_delete_generator_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient", - "shortName": "IntentsClient" + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsClient", + "shortName": "GeneratorsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient.batch_delete_intents", + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsClient.delete_generator", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Intents.BatchDeleteIntents", + "fullName": "google.cloud.dialogflow.v2beta1.Generators.DeleteGenerator", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Intents", - "shortName": "Intents" + "fullName": "google.cloud.dialogflow.v2beta1.Generators", + "shortName": "Generators" }, - "shortName": "BatchDeleteIntents" + "shortName": "DeleteGenerator" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.BatchDeleteIntentsRequest" + "type": "google.cloud.dialogflow_v2beta1.types.DeleteGeneratorRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, - { - "name": "intents", - "type": "MutableSequence[google.cloud.dialogflow_v2beta1.types.Intent]" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -11349,22 +11338,21 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.api_core.operation.Operation", - "shortName": "batch_delete_intents" + "shortName": "delete_generator" }, - "description": "Sample for BatchDeleteIntents", - "file": "dialogflow_v2beta1_generated_intents_batch_delete_intents_sync.py", + "description": "Sample for DeleteGenerator", + "file": "dialogflow_v2beta1_generated_generators_delete_generator_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Intents_BatchDeleteIntents_sync", + "regionTag": "dialogflow_v2beta1_generated_Generators_DeleteGenerator_sync", "segments": [ { - "end": 59, + "end": 49, "start": 27, "type": "FULL" }, { - "end": 59, + "end": 49, "start": 27, "type": "SHORT" }, @@ -11374,57 +11362,47 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 49, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 56, - "start": 50, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 60, - "start": 57, + "end": 50, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_intents_batch_delete_intents_sync.py" + "title": "dialogflow_v2beta1_generated_generators_delete_generator_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient", - "shortName": "IntentsAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsAsyncClient", + "shortName": "GeneratorsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient.batch_update_intents", + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsAsyncClient.get_generator", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Intents.BatchUpdateIntents", + "fullName": "google.cloud.dialogflow.v2beta1.Generators.GetGenerator", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Intents", - "shortName": "Intents" + "fullName": "google.cloud.dialogflow.v2beta1.Generators", + "shortName": "Generators" }, - "shortName": "BatchUpdateIntents" + "shortName": "GetGenerator" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.BatchUpdateIntentsRequest" - }, - { - "name": "parent", - "type": "str" + "type": "google.cloud.dialogflow_v2beta1.types.GetGeneratorRequest" }, { - "name": "intent_batch_uri", + "name": "name", "type": "str" }, - { - "name": "intent_batch_inline", - "type": "google.cloud.dialogflow_v2beta1.types.IntentBatch" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -11438,22 +11416,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.api_core.operation_async.AsyncOperation", - "shortName": "batch_update_intents" + "resultType": "google.cloud.dialogflow_v2beta1.types.Generator", + "shortName": "get_generator" }, - "description": "Sample for BatchUpdateIntents", - "file": "dialogflow_v2beta1_generated_intents_batch_update_intents_async.py", + "description": "Sample for GetGenerator", + "file": "dialogflow_v2beta1_generated_generators_get_generator_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Intents_BatchUpdateIntents_async", + "regionTag": "dialogflow_v2beta1_generated_Generators_GetGenerator_async", "segments": [ { - "end": 56, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 56, + "end": 51, "start": 27, "type": "SHORT" }, @@ -11463,56 +11441,48 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 46, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 53, - "start": 47, + "end": 48, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 57, - "start": 54, + "end": 52, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_intents_batch_update_intents_async.py" + "title": "dialogflow_v2beta1_generated_generators_get_generator_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient", - "shortName": "IntentsClient" + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsClient", + "shortName": "GeneratorsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient.batch_update_intents", + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsClient.get_generator", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Intents.BatchUpdateIntents", + "fullName": "google.cloud.dialogflow.v2beta1.Generators.GetGenerator", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Intents", - "shortName": "Intents" + "fullName": "google.cloud.dialogflow.v2beta1.Generators", + "shortName": "Generators" }, - "shortName": "BatchUpdateIntents" + "shortName": "GetGenerator" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.BatchUpdateIntentsRequest" - }, - { - "name": "parent", - "type": "str" + "type": "google.cloud.dialogflow_v2beta1.types.GetGeneratorRequest" }, { - "name": "intent_batch_uri", + "name": "name", "type": "str" }, - { - "name": "intent_batch_inline", - "type": "google.cloud.dialogflow_v2beta1.types.IntentBatch" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -11526,22 +11496,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.api_core.operation.Operation", - "shortName": "batch_update_intents" + "resultType": "google.cloud.dialogflow_v2beta1.types.Generator", + "shortName": "get_generator" }, - "description": "Sample for BatchUpdateIntents", - "file": "dialogflow_v2beta1_generated_intents_batch_update_intents_sync.py", + "description": "Sample for GetGenerator", + "file": "dialogflow_v2beta1_generated_generators_get_generator_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Intents_BatchUpdateIntents_sync", + "regionTag": "dialogflow_v2beta1_generated_Generators_GetGenerator_sync", "segments": [ { - "end": 56, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 56, + "end": 51, "start": 27, "type": "SHORT" }, @@ -11551,57 +11521,49 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 46, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 53, - "start": 47, + "end": 48, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 57, - "start": 54, + "end": 52, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_intents_batch_update_intents_sync.py" + "title": "dialogflow_v2beta1_generated_generators_get_generator_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient", - "shortName": "IntentsAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsAsyncClient", + "shortName": "GeneratorsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient.create_intent", + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsAsyncClient.list_generators", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Intents.CreateIntent", + "fullName": "google.cloud.dialogflow.v2beta1.Generators.ListGenerators", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Intents", - "shortName": "Intents" + "fullName": "google.cloud.dialogflow.v2beta1.Generators", + "shortName": "Generators" }, - "shortName": "CreateIntent" + "shortName": "ListGenerators" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.CreateIntentRequest" + "type": "google.cloud.dialogflow_v2beta1.types.ListGeneratorsRequest" }, { "name": "parent", "type": "str" }, - { - "name": "intent", - "type": "google.cloud.dialogflow_v2beta1.types.Intent" - }, - { - "name": "language_code", - "type": "str" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -11615,22 +11577,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.Intent", - "shortName": "create_intent" + "resultType": "google.cloud.dialogflow_v2beta1.services.generators.pagers.ListGeneratorsAsyncPager", + "shortName": "list_generators" }, - "description": "Sample for CreateIntent", - "file": "dialogflow_v2beta1_generated_intents_create_intent_async.py", + "description": "Sample for ListGenerators", + "file": "dialogflow_v2beta1_generated_generators_list_generators_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Intents_CreateIntent_async", + "regionTag": "dialogflow_v2beta1_generated_Generators_ListGenerators_async", "segments": [ { - "end": 55, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 55, + "end": 52, "start": 27, "type": "SHORT" }, @@ -11640,56 +11602,48 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 49, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 52, - "start": 50, + "end": 48, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 56, - "start": 53, + "end": 53, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_intents_create_intent_async.py" + "title": "dialogflow_v2beta1_generated_generators_list_generators_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient", - "shortName": "IntentsClient" + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsClient", + "shortName": "GeneratorsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient.create_intent", + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsClient.list_generators", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Intents.CreateIntent", + "fullName": "google.cloud.dialogflow.v2beta1.Generators.ListGenerators", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Intents", - "shortName": "Intents" + "fullName": "google.cloud.dialogflow.v2beta1.Generators", + "shortName": "Generators" }, - "shortName": "CreateIntent" + "shortName": "ListGenerators" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.CreateIntentRequest" + "type": "google.cloud.dialogflow_v2beta1.types.ListGeneratorsRequest" }, { "name": "parent", "type": "str" }, - { - "name": "intent", - "type": "google.cloud.dialogflow_v2beta1.types.Intent" - }, - { - "name": "language_code", - "type": "str" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -11703,22 +11657,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.Intent", - "shortName": "create_intent" + "resultType": "google.cloud.dialogflow_v2beta1.services.generators.pagers.ListGeneratorsPager", + "shortName": "list_generators" }, - "description": "Sample for CreateIntent", - "file": "dialogflow_v2beta1_generated_intents_create_intent_sync.py", + "description": "Sample for ListGenerators", + "file": "dialogflow_v2beta1_generated_generators_list_generators_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Intents_CreateIntent_sync", + "regionTag": "dialogflow_v2beta1_generated_Generators_ListGenerators_sync", "segments": [ { - "end": 55, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 55, + "end": 52, "start": 27, "type": "SHORT" }, @@ -11728,48 +11682,52 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 49, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 52, - "start": 50, + "end": 48, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 56, - "start": 53, + "end": 53, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_intents_create_intent_sync.py" + "title": "dialogflow_v2beta1_generated_generators_list_generators_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient", - "shortName": "IntentsAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsAsyncClient", + "shortName": "GeneratorsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient.delete_intent", + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsAsyncClient.update_generator", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Intents.DeleteIntent", + "fullName": "google.cloud.dialogflow.v2beta1.Generators.UpdateGenerator", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Intents", - "shortName": "Intents" + "fullName": "google.cloud.dialogflow.v2beta1.Generators", + "shortName": "Generators" }, - "shortName": "DeleteIntent" + "shortName": "UpdateGenerator" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.DeleteIntentRequest" + "type": "google.cloud.dialogflow_v2beta1.types.UpdateGeneratorRequest" }, { - "name": "name", - "type": "str" + "name": "generator", + "type": "google.cloud.dialogflow_v2beta1.types.Generator" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" }, { "name": "retry", @@ -11784,21 +11742,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "shortName": "delete_intent" + "resultType": "google.cloud.dialogflow_v2beta1.types.Generator", + "shortName": "update_generator" }, - "description": "Sample for DeleteIntent", - "file": "dialogflow_v2beta1_generated_intents_delete_intent_async.py", + "description": "Sample for UpdateGenerator", + "file": "dialogflow_v2beta1_generated_generators_update_generator_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Intents_DeleteIntent_async", + "regionTag": "dialogflow_v2beta1_generated_Generators_UpdateGenerator_async", "segments": [ { - "end": 49, + "end": 54, "start": 27, "type": "FULL" }, { - "end": 49, + "end": 54, "start": 27, "type": "SHORT" }, @@ -11808,45 +11767,51 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 48, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "start": 46, + "end": 51, + "start": 49, "type": "REQUEST_EXECUTION" }, { - "end": 50, + "end": 55, + "start": 52, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_intents_delete_intent_async.py" + "title": "dialogflow_v2beta1_generated_generators_update_generator_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient", - "shortName": "IntentsClient" + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsClient", + "shortName": "GeneratorsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient.delete_intent", + "fullName": "google.cloud.dialogflow_v2beta1.GeneratorsClient.update_generator", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Intents.DeleteIntent", + "fullName": "google.cloud.dialogflow.v2beta1.Generators.UpdateGenerator", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Intents", - "shortName": "Intents" + "fullName": "google.cloud.dialogflow.v2beta1.Generators", + "shortName": "Generators" }, - "shortName": "DeleteIntent" + "shortName": "UpdateGenerator" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.DeleteIntentRequest" + "type": "google.cloud.dialogflow_v2beta1.types.UpdateGeneratorRequest" }, { - "name": "name", - "type": "str" + "name": "generator", + "type": "google.cloud.dialogflow_v2beta1.types.Generator" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" }, { "name": "retry", @@ -11861,21 +11826,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "shortName": "delete_intent" + "resultType": "google.cloud.dialogflow_v2beta1.types.Generator", + "shortName": "update_generator" }, - "description": "Sample for DeleteIntent", - "file": "dialogflow_v2beta1_generated_intents_delete_intent_sync.py", + "description": "Sample for UpdateGenerator", + "file": "dialogflow_v2beta1_generated_generators_update_generator_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Intents_DeleteIntent_sync", + "regionTag": "dialogflow_v2beta1_generated_Generators_UpdateGenerator_sync", "segments": [ { - "end": 49, + "end": 54, "start": 27, "type": "FULL" }, { - "end": 49, + "end": 54, "start": 27, "type": "SHORT" }, @@ -11885,20 +11851,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 48, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "start": 46, + "end": 51, + "start": 49, "type": "REQUEST_EXECUTION" }, { - "end": 50, + "end": 55, + "start": 52, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_intents_delete_intent_sync.py" + "title": "dialogflow_v2beta1_generated_generators_update_generator_sync.py" }, { "canonical": true, @@ -11908,27 +11876,27 @@ "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient", "shortName": "IntentsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient.get_intent", + "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient.batch_delete_intents", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Intents.GetIntent", + "fullName": "google.cloud.dialogflow.v2beta1.Intents.BatchDeleteIntents", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Intents", "shortName": "Intents" }, - "shortName": "GetIntent" + "shortName": "BatchDeleteIntents" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.GetIntentRequest" + "type": "google.cloud.dialogflow_v2beta1.types.BatchDeleteIntentsRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { - "name": "language_code", - "type": "str" + "name": "intents", + "type": "MutableSequence[google.cloud.dialogflow_v2beta1.types.Intent]" }, { "name": "retry", @@ -11943,22 +11911,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.Intent", - "shortName": "get_intent" + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "batch_delete_intents" }, - "description": "Sample for GetIntent", - "file": "dialogflow_v2beta1_generated_intents_get_intent_async.py", + "description": "Sample for BatchDeleteIntents", + "file": "dialogflow_v2beta1_generated_intents_batch_delete_intents_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Intents_GetIntent_async", + "regionTag": "dialogflow_v2beta1_generated_Intents_BatchDeleteIntents_async", "segments": [ { - "end": 51, + "end": 59, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 59, "start": 27, "type": "SHORT" }, @@ -11968,22 +11936,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 49, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 56, + "start": 50, "type": "REQUEST_EXECUTION" }, { - "end": 52, - "start": 49, + "end": 60, + "start": 57, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_intents_get_intent_async.py" + "title": "dialogflow_v2beta1_generated_intents_batch_delete_intents_async.py" }, { "canonical": true, @@ -11992,27 +11960,27 @@ "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient", "shortName": "IntentsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient.get_intent", + "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient.batch_delete_intents", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Intents.GetIntent", + "fullName": "google.cloud.dialogflow.v2beta1.Intents.BatchDeleteIntents", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Intents", "shortName": "Intents" }, - "shortName": "GetIntent" + "shortName": "BatchDeleteIntents" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.GetIntentRequest" + "type": "google.cloud.dialogflow_v2beta1.types.BatchDeleteIntentsRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { - "name": "language_code", - "type": "str" + "name": "intents", + "type": "MutableSequence[google.cloud.dialogflow_v2beta1.types.Intent]" }, { "name": "retry", @@ -12027,22 +11995,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.Intent", - "shortName": "get_intent" + "resultType": "google.api_core.operation.Operation", + "shortName": "batch_delete_intents" }, - "description": "Sample for GetIntent", - "file": "dialogflow_v2beta1_generated_intents_get_intent_sync.py", + "description": "Sample for BatchDeleteIntents", + "file": "dialogflow_v2beta1_generated_intents_batch_delete_intents_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Intents_GetIntent_sync", + "regionTag": "dialogflow_v2beta1_generated_Intents_BatchDeleteIntents_sync", "segments": [ { - "end": 51, + "end": 59, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 59, "start": 27, "type": "SHORT" }, @@ -12052,22 +12020,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 49, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 56, + "start": 50, "type": "REQUEST_EXECUTION" }, { - "end": 52, - "start": 49, + "end": 60, + "start": 57, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_intents_get_intent_sync.py" + "title": "dialogflow_v2beta1_generated_intents_batch_delete_intents_sync.py" }, { "canonical": true, @@ -12077,28 +12045,32 @@ "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient", "shortName": "IntentsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient.list_intents", + "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient.batch_update_intents", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Intents.ListIntents", + "fullName": "google.cloud.dialogflow.v2beta1.Intents.BatchUpdateIntents", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Intents", "shortName": "Intents" }, - "shortName": "ListIntents" + "shortName": "BatchUpdateIntents" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.ListIntentsRequest" + "type": "google.cloud.dialogflow_v2beta1.types.BatchUpdateIntentsRequest" }, { "name": "parent", "type": "str" }, { - "name": "language_code", + "name": "intent_batch_uri", "type": "str" }, + { + "name": "intent_batch_inline", + "type": "google.cloud.dialogflow_v2beta1.types.IntentBatch" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -12112,22 +12084,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.services.intents.pagers.ListIntentsAsyncPager", - "shortName": "list_intents" + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "batch_update_intents" }, - "description": "Sample for ListIntents", - "file": "dialogflow_v2beta1_generated_intents_list_intents_async.py", + "description": "Sample for BatchUpdateIntents", + "file": "dialogflow_v2beta1_generated_intents_batch_update_intents_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Intents_ListIntents_async", + "regionTag": "dialogflow_v2beta1_generated_Intents_BatchUpdateIntents_async", "segments": [ { - "end": 52, + "end": 56, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 56, "start": 27, "type": "SHORT" }, @@ -12137,22 +12109,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 46, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 53, + "start": 47, "type": "REQUEST_EXECUTION" }, { - "end": 53, - "start": 49, + "end": 57, + "start": 54, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_intents_list_intents_async.py" + "title": "dialogflow_v2beta1_generated_intents_batch_update_intents_async.py" }, { "canonical": true, @@ -12161,28 +12133,32 @@ "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient", "shortName": "IntentsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient.list_intents", + "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient.batch_update_intents", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Intents.ListIntents", + "fullName": "google.cloud.dialogflow.v2beta1.Intents.BatchUpdateIntents", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Intents", "shortName": "Intents" }, - "shortName": "ListIntents" + "shortName": "BatchUpdateIntents" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.ListIntentsRequest" + "type": "google.cloud.dialogflow_v2beta1.types.BatchUpdateIntentsRequest" }, { "name": "parent", "type": "str" }, { - "name": "language_code", + "name": "intent_batch_uri", "type": "str" }, + { + "name": "intent_batch_inline", + "type": "google.cloud.dialogflow_v2beta1.types.IntentBatch" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -12196,22 +12172,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.services.intents.pagers.ListIntentsPager", - "shortName": "list_intents" + "resultType": "google.api_core.operation.Operation", + "shortName": "batch_update_intents" }, - "description": "Sample for ListIntents", - "file": "dialogflow_v2beta1_generated_intents_list_intents_sync.py", + "description": "Sample for BatchUpdateIntents", + "file": "dialogflow_v2beta1_generated_intents_batch_update_intents_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Intents_ListIntents_sync", + "regionTag": "dialogflow_v2beta1_generated_Intents_BatchUpdateIntents_sync", "segments": [ { - "end": 52, + "end": 56, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 56, "start": 27, "type": "SHORT" }, @@ -12221,22 +12197,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 46, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 53, + "start": 47, "type": "REQUEST_EXECUTION" }, { - "end": 53, - "start": 49, + "end": 57, + "start": 54, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_intents_list_intents_sync.py" + "title": "dialogflow_v2beta1_generated_intents_batch_update_intents_sync.py" }, { "canonical": true, @@ -12246,27 +12222,27 @@ "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient", "shortName": "IntentsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient.update_intent", + "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient.create_intent", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Intents.UpdateIntent", + "fullName": "google.cloud.dialogflow.v2beta1.Intents.CreateIntent", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Intents", "shortName": "Intents" }, - "shortName": "UpdateIntent" + "shortName": "CreateIntent" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.UpdateIntentRequest" + "type": "google.cloud.dialogflow_v2beta1.types.CreateIntentRequest" }, { - "name": "intent", - "type": "google.cloud.dialogflow_v2beta1.types.Intent" + "name": "parent", + "type": "str" }, { - "name": "update_mask", - "type": "google.protobuf.field_mask_pb2.FieldMask" + "name": "intent", + "type": "google.cloud.dialogflow_v2beta1.types.Intent" }, { "name": "language_code", @@ -12286,21 +12262,21 @@ } ], "resultType": "google.cloud.dialogflow_v2beta1.types.Intent", - "shortName": "update_intent" + "shortName": "create_intent" }, - "description": "Sample for UpdateIntent", - "file": "dialogflow_v2beta1_generated_intents_update_intent_async.py", + "description": "Sample for CreateIntent", + "file": "dialogflow_v2beta1_generated_intents_create_intent_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Intents_UpdateIntent_async", + "regionTag": "dialogflow_v2beta1_generated_Intents_CreateIntent_async", "segments": [ { - "end": 54, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 54, + "end": 55, "start": 27, "type": "SHORT" }, @@ -12310,22 +12286,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 48, + "end": 49, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 51, - "start": 49, + "end": 52, + "start": 50, "type": "REQUEST_EXECUTION" }, { - "end": 55, - "start": 52, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_intents_update_intent_async.py" + "title": "dialogflow_v2beta1_generated_intents_create_intent_async.py" }, { "canonical": true, @@ -12334,27 +12310,27 @@ "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient", "shortName": "IntentsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient.update_intent", + "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient.create_intent", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Intents.UpdateIntent", + "fullName": "google.cloud.dialogflow.v2beta1.Intents.CreateIntent", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Intents", "shortName": "Intents" }, - "shortName": "UpdateIntent" + "shortName": "CreateIntent" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.UpdateIntentRequest" + "type": "google.cloud.dialogflow_v2beta1.types.CreateIntentRequest" }, { - "name": "intent", - "type": "google.cloud.dialogflow_v2beta1.types.Intent" + "name": "parent", + "type": "str" }, { - "name": "update_mask", - "type": "google.protobuf.field_mask_pb2.FieldMask" + "name": "intent", + "type": "google.cloud.dialogflow_v2beta1.types.Intent" }, { "name": "language_code", @@ -12374,21 +12350,21 @@ } ], "resultType": "google.cloud.dialogflow_v2beta1.types.Intent", - "shortName": "update_intent" + "shortName": "create_intent" }, - "description": "Sample for UpdateIntent", - "file": "dialogflow_v2beta1_generated_intents_update_intent_sync.py", + "description": "Sample for CreateIntent", + "file": "dialogflow_v2beta1_generated_intents_create_intent_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Intents_UpdateIntent_sync", + "regionTag": "dialogflow_v2beta1_generated_Intents_CreateIntent_sync", "segments": [ { - "end": 54, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 54, + "end": 55, "start": 27, "type": "SHORT" }, @@ -12398,53 +12374,49 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 48, + "end": 49, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 51, - "start": 49, + "end": 52, + "start": 50, "type": "REQUEST_EXECUTION" }, { - "end": 55, - "start": 52, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_intents_update_intent_sync.py" + "title": "dialogflow_v2beta1_generated_intents_create_intent_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesAsyncClient", - "shortName": "KnowledgeBasesAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient", + "shortName": "IntentsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesAsyncClient.create_knowledge_base", + "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient.delete_intent", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases.CreateKnowledgeBase", + "fullName": "google.cloud.dialogflow.v2beta1.Intents.DeleteIntent", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases", - "shortName": "KnowledgeBases" + "fullName": "google.cloud.dialogflow.v2beta1.Intents", + "shortName": "Intents" }, - "shortName": "CreateKnowledgeBase" + "shortName": "DeleteIntent" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.CreateKnowledgeBaseRequest" + "type": "google.cloud.dialogflow_v2beta1.types.DeleteIntentRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, - { - "name": "knowledge_base", - "type": "google.cloud.dialogflow_v2beta1.types.KnowledgeBase" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -12458,22 +12430,21 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.KnowledgeBase", - "shortName": "create_knowledge_base" + "shortName": "delete_intent" }, - "description": "Sample for CreateKnowledgeBase", - "file": "dialogflow_v2beta1_generated_knowledge_bases_create_knowledge_base_async.py", + "description": "Sample for DeleteIntent", + "file": "dialogflow_v2beta1_generated_intents_delete_intent_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_KnowledgeBases_CreateKnowledgeBase_async", + "regionTag": "dialogflow_v2beta1_generated_Intents_DeleteIntent_async", "segments": [ { - "end": 55, + "end": 49, "start": 27, "type": "FULL" }, { - "end": 55, + "end": 49, "start": 27, "type": "SHORT" }, @@ -12483,52 +12454,46 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 49, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 52, - "start": 50, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 56, - "start": 53, + "end": 50, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_knowledge_bases_create_knowledge_base_async.py" + "title": "dialogflow_v2beta1_generated_intents_delete_intent_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesClient", - "shortName": "KnowledgeBasesClient" + "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient", + "shortName": "IntentsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesClient.create_knowledge_base", + "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient.delete_intent", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases.CreateKnowledgeBase", + "fullName": "google.cloud.dialogflow.v2beta1.Intents.DeleteIntent", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases", - "shortName": "KnowledgeBases" + "fullName": "google.cloud.dialogflow.v2beta1.Intents", + "shortName": "Intents" }, - "shortName": "CreateKnowledgeBase" + "shortName": "DeleteIntent" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.CreateKnowledgeBaseRequest" + "type": "google.cloud.dialogflow_v2beta1.types.DeleteIntentRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, - { - "name": "knowledge_base", - "type": "google.cloud.dialogflow_v2beta1.types.KnowledgeBase" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -12542,22 +12507,21 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.KnowledgeBase", - "shortName": "create_knowledge_base" + "shortName": "delete_intent" }, - "description": "Sample for CreateKnowledgeBase", - "file": "dialogflow_v2beta1_generated_knowledge_bases_create_knowledge_base_sync.py", + "description": "Sample for DeleteIntent", + "file": "dialogflow_v2beta1_generated_intents_delete_intent_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_KnowledgeBases_CreateKnowledgeBase_sync", + "regionTag": "dialogflow_v2beta1_generated_Intents_DeleteIntent_sync", "segments": [ { - "end": 55, + "end": 49, "start": 27, "type": "FULL" }, { - "end": 55, + "end": 49, "start": 27, "type": "SHORT" }, @@ -12567,49 +12531,51 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 49, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 52, - "start": 50, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 56, - "start": 53, + "end": 50, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_knowledge_bases_create_knowledge_base_sync.py" + "title": "dialogflow_v2beta1_generated_intents_delete_intent_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesAsyncClient", - "shortName": "KnowledgeBasesAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient", + "shortName": "IntentsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesAsyncClient.delete_knowledge_base", + "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient.get_intent", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases.DeleteKnowledgeBase", + "fullName": "google.cloud.dialogflow.v2beta1.Intents.GetIntent", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases", - "shortName": "KnowledgeBases" + "fullName": "google.cloud.dialogflow.v2beta1.Intents", + "shortName": "Intents" }, - "shortName": "DeleteKnowledgeBase" + "shortName": "GetIntent" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.DeleteKnowledgeBaseRequest" + "type": "google.cloud.dialogflow_v2beta1.types.GetIntentRequest" }, { "name": "name", "type": "str" }, + { + "name": "language_code", + "type": "str" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -12623,21 +12589,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "shortName": "delete_knowledge_base" + "resultType": "google.cloud.dialogflow_v2beta1.types.Intent", + "shortName": "get_intent" }, - "description": "Sample for DeleteKnowledgeBase", - "file": "dialogflow_v2beta1_generated_knowledge_bases_delete_knowledge_base_async.py", + "description": "Sample for GetIntent", + "file": "dialogflow_v2beta1_generated_intents_get_intent_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_KnowledgeBases_DeleteKnowledgeBase_async", + "regionTag": "dialogflow_v2beta1_generated_Intents_GetIntent_async", "segments": [ { - "end": 49, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 49, + "end": 51, "start": 27, "type": "SHORT" }, @@ -12652,41 +12619,47 @@ "type": "REQUEST_INITIALIZATION" }, { + "end": 48, "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 50, + "end": 52, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_knowledge_bases_delete_knowledge_base_async.py" + "title": "dialogflow_v2beta1_generated_intents_get_intent_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesClient", - "shortName": "KnowledgeBasesClient" + "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient", + "shortName": "IntentsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesClient.delete_knowledge_base", + "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient.get_intent", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases.DeleteKnowledgeBase", + "fullName": "google.cloud.dialogflow.v2beta1.Intents.GetIntent", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases", - "shortName": "KnowledgeBases" + "fullName": "google.cloud.dialogflow.v2beta1.Intents", + "shortName": "Intents" }, - "shortName": "DeleteKnowledgeBase" + "shortName": "GetIntent" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.DeleteKnowledgeBaseRequest" + "type": "google.cloud.dialogflow_v2beta1.types.GetIntentRequest" }, { "name": "name", "type": "str" }, + { + "name": "language_code", + "type": "str" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -12700,21 +12673,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "shortName": "delete_knowledge_base" + "resultType": "google.cloud.dialogflow_v2beta1.types.Intent", + "shortName": "get_intent" }, - "description": "Sample for DeleteKnowledgeBase", - "file": "dialogflow_v2beta1_generated_knowledge_bases_delete_knowledge_base_sync.py", + "description": "Sample for GetIntent", + "file": "dialogflow_v2beta1_generated_intents_get_intent_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_KnowledgeBases_DeleteKnowledgeBase_sync", + "regionTag": "dialogflow_v2beta1_generated_Intents_GetIntent_sync", "segments": [ { - "end": 49, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 49, + "end": 51, "start": 27, "type": "SHORT" }, @@ -12729,40 +12703,46 @@ "type": "REQUEST_INITIALIZATION" }, { + "end": 48, "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 50, + "end": 52, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_knowledge_bases_delete_knowledge_base_sync.py" + "title": "dialogflow_v2beta1_generated_intents_get_intent_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesAsyncClient", - "shortName": "KnowledgeBasesAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient", + "shortName": "IntentsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesAsyncClient.get_knowledge_base", + "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient.list_intents", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases.GetKnowledgeBase", + "fullName": "google.cloud.dialogflow.v2beta1.Intents.ListIntents", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases", - "shortName": "KnowledgeBases" + "fullName": "google.cloud.dialogflow.v2beta1.Intents", + "shortName": "Intents" }, - "shortName": "GetKnowledgeBase" + "shortName": "ListIntents" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.GetKnowledgeBaseRequest" + "type": "google.cloud.dialogflow_v2beta1.types.ListIntentsRequest" }, { - "name": "name", + "name": "parent", + "type": "str" + }, + { + "name": "language_code", "type": "str" }, { @@ -12778,22 +12758,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.KnowledgeBase", - "shortName": "get_knowledge_base" + "resultType": "google.cloud.dialogflow_v2beta1.services.intents.pagers.ListIntentsAsyncPager", + "shortName": "list_intents" }, - "description": "Sample for GetKnowledgeBase", - "file": "dialogflow_v2beta1_generated_knowledge_bases_get_knowledge_base_async.py", + "description": "Sample for ListIntents", + "file": "dialogflow_v2beta1_generated_intents_list_intents_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_KnowledgeBases_GetKnowledgeBase_async", + "regionTag": "dialogflow_v2beta1_generated_Intents_ListIntents_async", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -12813,36 +12793,40 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_knowledge_bases_get_knowledge_base_async.py" + "title": "dialogflow_v2beta1_generated_intents_list_intents_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesClient", - "shortName": "KnowledgeBasesClient" + "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient", + "shortName": "IntentsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesClient.get_knowledge_base", + "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient.list_intents", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases.GetKnowledgeBase", + "fullName": "google.cloud.dialogflow.v2beta1.Intents.ListIntents", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases", - "shortName": "KnowledgeBases" + "fullName": "google.cloud.dialogflow.v2beta1.Intents", + "shortName": "Intents" }, - "shortName": "GetKnowledgeBase" + "shortName": "ListIntents" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.GetKnowledgeBaseRequest" + "type": "google.cloud.dialogflow_v2beta1.types.ListIntentsRequest" }, { - "name": "name", + "name": "parent", + "type": "str" + }, + { + "name": "language_code", "type": "str" }, { @@ -12858,22 +12842,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.KnowledgeBase", - "shortName": "get_knowledge_base" + "resultType": "google.cloud.dialogflow_v2beta1.services.intents.pagers.ListIntentsPager", + "shortName": "list_intents" }, - "description": "Sample for GetKnowledgeBase", - "file": "dialogflow_v2beta1_generated_knowledge_bases_get_knowledge_base_sync.py", + "description": "Sample for ListIntents", + "file": "dialogflow_v2beta1_generated_intents_list_intents_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_KnowledgeBases_GetKnowledgeBase_sync", + "regionTag": "dialogflow_v2beta1_generated_Intents_ListIntents_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -12893,37 +12877,45 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_knowledge_bases_get_knowledge_base_sync.py" + "title": "dialogflow_v2beta1_generated_intents_list_intents_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesAsyncClient", - "shortName": "KnowledgeBasesAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient", + "shortName": "IntentsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesAsyncClient.list_knowledge_bases", + "fullName": "google.cloud.dialogflow_v2beta1.IntentsAsyncClient.update_intent", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases.ListKnowledgeBases", + "fullName": "google.cloud.dialogflow.v2beta1.Intents.UpdateIntent", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases", - "shortName": "KnowledgeBases" + "fullName": "google.cloud.dialogflow.v2beta1.Intents", + "shortName": "Intents" }, - "shortName": "ListKnowledgeBases" + "shortName": "UpdateIntent" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.ListKnowledgeBasesRequest" + "type": "google.cloud.dialogflow_v2beta1.types.UpdateIntentRequest" }, { - "name": "parent", + "name": "intent", + "type": "google.cloud.dialogflow_v2beta1.types.Intent" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "language_code", "type": "str" }, { @@ -12939,22 +12931,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.services.knowledge_bases.pagers.ListKnowledgeBasesAsyncPager", - "shortName": "list_knowledge_bases" + "resultType": "google.cloud.dialogflow_v2beta1.types.Intent", + "shortName": "update_intent" }, - "description": "Sample for ListKnowledgeBases", - "file": "dialogflow_v2beta1_generated_knowledge_bases_list_knowledge_bases_async.py", + "description": "Sample for UpdateIntent", + "file": "dialogflow_v2beta1_generated_intents_update_intent_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_KnowledgeBases_ListKnowledgeBases_async", + "regionTag": "dialogflow_v2beta1_generated_Intents_UpdateIntent_async", "segments": [ { - "end": 52, + "end": 54, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 54, "start": 27, "type": "SHORT" }, @@ -12964,46 +12956,54 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 48, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 51, + "start": 49, "type": "REQUEST_EXECUTION" }, { - "end": 53, - "start": 49, + "end": 55, + "start": 52, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_knowledge_bases_list_knowledge_bases_async.py" + "title": "dialogflow_v2beta1_generated_intents_update_intent_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesClient", - "shortName": "KnowledgeBasesClient" + "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient", + "shortName": "IntentsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesClient.list_knowledge_bases", + "fullName": "google.cloud.dialogflow_v2beta1.IntentsClient.update_intent", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases.ListKnowledgeBases", + "fullName": "google.cloud.dialogflow.v2beta1.Intents.UpdateIntent", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases", - "shortName": "KnowledgeBases" + "fullName": "google.cloud.dialogflow.v2beta1.Intents", + "shortName": "Intents" }, - "shortName": "ListKnowledgeBases" + "shortName": "UpdateIntent" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.ListKnowledgeBasesRequest" + "type": "google.cloud.dialogflow_v2beta1.types.UpdateIntentRequest" }, { - "name": "parent", + "name": "intent", + "type": "google.cloud.dialogflow_v2beta1.types.Intent" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "language_code", "type": "str" }, { @@ -13019,22 +13019,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.services.knowledge_bases.pagers.ListKnowledgeBasesPager", - "shortName": "list_knowledge_bases" + "resultType": "google.cloud.dialogflow_v2beta1.types.Intent", + "shortName": "update_intent" }, - "description": "Sample for ListKnowledgeBases", - "file": "dialogflow_v2beta1_generated_knowledge_bases_list_knowledge_bases_sync.py", + "description": "Sample for UpdateIntent", + "file": "dialogflow_v2beta1_generated_intents_update_intent_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_KnowledgeBases_ListKnowledgeBases_sync", + "regionTag": "dialogflow_v2beta1_generated_Intents_UpdateIntent_sync", "segments": [ { - "end": 52, + "end": 54, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 54, "start": 27, "type": "SHORT" }, @@ -13044,22 +13044,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 48, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 51, + "start": 49, "type": "REQUEST_EXECUTION" }, { - "end": 53, - "start": 49, + "end": 55, + "start": 52, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_knowledge_bases_list_knowledge_bases_sync.py" + "title": "dialogflow_v2beta1_generated_intents_update_intent_sync.py" }, { "canonical": true, @@ -13069,27 +13069,27 @@ "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesAsyncClient", "shortName": "KnowledgeBasesAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesAsyncClient.update_knowledge_base", + "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesAsyncClient.create_knowledge_base", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases.UpdateKnowledgeBase", + "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases.CreateKnowledgeBase", "service": { "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases", "shortName": "KnowledgeBases" }, - "shortName": "UpdateKnowledgeBase" + "shortName": "CreateKnowledgeBase" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.UpdateKnowledgeBaseRequest" + "type": "google.cloud.dialogflow_v2beta1.types.CreateKnowledgeBaseRequest" }, { - "name": "knowledge_base", - "type": "google.cloud.dialogflow_v2beta1.types.KnowledgeBase" + "name": "parent", + "type": "str" }, { - "name": "update_mask", - "type": "google.protobuf.field_mask_pb2.FieldMask" + "name": "knowledge_base", + "type": "google.cloud.dialogflow_v2beta1.types.KnowledgeBase" }, { "name": "retry", @@ -13105,21 +13105,21 @@ } ], "resultType": "google.cloud.dialogflow_v2beta1.types.KnowledgeBase", - "shortName": "update_knowledge_base" + "shortName": "create_knowledge_base" }, - "description": "Sample for UpdateKnowledgeBase", - "file": "dialogflow_v2beta1_generated_knowledge_bases_update_knowledge_base_async.py", + "description": "Sample for CreateKnowledgeBase", + "file": "dialogflow_v2beta1_generated_knowledge_bases_create_knowledge_base_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_KnowledgeBases_UpdateKnowledgeBase_async", + "regionTag": "dialogflow_v2beta1_generated_KnowledgeBases_CreateKnowledgeBase_async", "segments": [ { - "end": 54, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 54, + "end": 55, "start": 27, "type": "SHORT" }, @@ -13129,22 +13129,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 48, + "end": 49, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 51, - "start": 49, + "end": 52, + "start": 50, "type": "REQUEST_EXECUTION" }, { - "end": 55, - "start": 52, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_knowledge_bases_update_knowledge_base_async.py" + "title": "dialogflow_v2beta1_generated_knowledge_bases_create_knowledge_base_async.py" }, { "canonical": true, @@ -13153,27 +13153,27 @@ "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesClient", "shortName": "KnowledgeBasesClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesClient.update_knowledge_base", + "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesClient.create_knowledge_base", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases.UpdateKnowledgeBase", + "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases.CreateKnowledgeBase", "service": { "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases", "shortName": "KnowledgeBases" }, - "shortName": "UpdateKnowledgeBase" + "shortName": "CreateKnowledgeBase" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.UpdateKnowledgeBaseRequest" + "type": "google.cloud.dialogflow_v2beta1.types.CreateKnowledgeBaseRequest" }, { - "name": "knowledge_base", - "type": "google.cloud.dialogflow_v2beta1.types.KnowledgeBase" + "name": "parent", + "type": "str" }, { - "name": "update_mask", - "type": "google.protobuf.field_mask_pb2.FieldMask" + "name": "knowledge_base", + "type": "google.cloud.dialogflow_v2beta1.types.KnowledgeBase" }, { "name": "retry", @@ -13189,21 +13189,21 @@ } ], "resultType": "google.cloud.dialogflow_v2beta1.types.KnowledgeBase", - "shortName": "update_knowledge_base" + "shortName": "create_knowledge_base" }, - "description": "Sample for UpdateKnowledgeBase", - "file": "dialogflow_v2beta1_generated_knowledge_bases_update_knowledge_base_sync.py", + "description": "Sample for CreateKnowledgeBase", + "file": "dialogflow_v2beta1_generated_knowledge_bases_create_knowledge_base_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_KnowledgeBases_UpdateKnowledgeBase_sync", + "regionTag": "dialogflow_v2beta1_generated_KnowledgeBases_CreateKnowledgeBase_sync", "segments": [ { - "end": 54, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 54, + "end": 55, "start": 27, "type": "SHORT" }, @@ -13213,61 +13213,49 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 48, + "end": 49, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 51, - "start": 49, + "end": 52, + "start": 50, "type": "REQUEST_EXECUTION" }, { - "end": 55, - "start": 52, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_knowledge_bases_update_knowledge_base_sync.py" + "title": "dialogflow_v2beta1_generated_knowledge_bases_create_knowledge_base_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient", - "shortName": "ParticipantsAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesAsyncClient", + "shortName": "KnowledgeBasesAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.analyze_content", + "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesAsyncClient.delete_knowledge_base", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.AnalyzeContent", + "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases.DeleteKnowledgeBase", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants", - "shortName": "Participants" + "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases", + "shortName": "KnowledgeBases" }, - "shortName": "AnalyzeContent" + "shortName": "DeleteKnowledgeBase" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.AnalyzeContentRequest" + "type": "google.cloud.dialogflow_v2beta1.types.DeleteKnowledgeBaseRequest" }, { - "name": "participant", + "name": "name", "type": "str" }, - { - "name": "text_input", - "type": "google.cloud.dialogflow_v2beta1.types.TextInput" - }, - { - "name": "audio_input", - "type": "google.cloud.dialogflow_v2beta1.types.AudioInput" - }, - { - "name": "event_input", - "type": "google.cloud.dialogflow_v2beta1.types.EventInput" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -13281,22 +13269,21 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.AnalyzeContentResponse", - "shortName": "analyze_content" + "shortName": "delete_knowledge_base" }, - "description": "Sample for AnalyzeContent", - "file": "dialogflow_v2beta1_generated_participants_analyze_content_async.py", + "description": "Sample for DeleteKnowledgeBase", + "file": "dialogflow_v2beta1_generated_knowledge_bases_delete_knowledge_base_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_AnalyzeContent_async", + "regionTag": "dialogflow_v2beta1_generated_KnowledgeBases_DeleteKnowledgeBase_async", "segments": [ { - "end": 51, + "end": 49, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 49, "start": 27, "type": "SHORT" }, @@ -13311,55 +13298,41 @@ "type": "REQUEST_INITIALIZATION" }, { - "end": 48, "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 52, - "start": 49, + "end": 50, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_analyze_content_async.py" + "title": "dialogflow_v2beta1_generated_knowledge_bases_delete_knowledge_base_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient", - "shortName": "ParticipantsClient" + "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesClient", + "shortName": "KnowledgeBasesClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.analyze_content", + "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesClient.delete_knowledge_base", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.AnalyzeContent", + "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases.DeleteKnowledgeBase", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants", - "shortName": "Participants" + "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases", + "shortName": "KnowledgeBases" }, - "shortName": "AnalyzeContent" + "shortName": "DeleteKnowledgeBase" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.AnalyzeContentRequest" + "type": "google.cloud.dialogflow_v2beta1.types.DeleteKnowledgeBaseRequest" }, { - "name": "participant", + "name": "name", "type": "str" }, - { - "name": "text_input", - "type": "google.cloud.dialogflow_v2beta1.types.TextInput" - }, - { - "name": "audio_input", - "type": "google.cloud.dialogflow_v2beta1.types.AudioInput" - }, - { - "name": "event_input", - "type": "google.cloud.dialogflow_v2beta1.types.EventInput" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -13373,22 +13346,21 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.AnalyzeContentResponse", - "shortName": "analyze_content" + "shortName": "delete_knowledge_base" }, - "description": "Sample for AnalyzeContent", - "file": "dialogflow_v2beta1_generated_participants_analyze_content_sync.py", + "description": "Sample for DeleteKnowledgeBase", + "file": "dialogflow_v2beta1_generated_knowledge_bases_delete_knowledge_base_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_AnalyzeContent_sync", + "regionTag": "dialogflow_v2beta1_generated_KnowledgeBases_DeleteKnowledgeBase_sync", "segments": [ { - "end": 51, + "end": 49, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 49, "start": 27, "type": "SHORT" }, @@ -13403,39 +13375,41 @@ "type": "REQUEST_INITIALIZATION" }, { - "end": 48, "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 52, - "start": 49, + "end": 50, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_analyze_content_sync.py" + "title": "dialogflow_v2beta1_generated_knowledge_bases_delete_knowledge_base_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient", - "shortName": "ParticipantsAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesAsyncClient", + "shortName": "KnowledgeBasesAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.compile_suggestion", + "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesAsyncClient.get_knowledge_base", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.CompileSuggestion", + "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases.GetKnowledgeBase", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants", - "shortName": "Participants" + "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases", + "shortName": "KnowledgeBases" }, - "shortName": "CompileSuggestion" + "shortName": "GetKnowledgeBase" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.CompileSuggestionRequest" + "type": "google.cloud.dialogflow_v2beta1.types.GetKnowledgeBaseRequest" + }, + { + "name": "name", + "type": "str" }, { "name": "retry", @@ -13450,22 +13424,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.CompileSuggestionResponse", - "shortName": "compile_suggestion" + "resultType": "google.cloud.dialogflow_v2beta1.types.KnowledgeBase", + "shortName": "get_knowledge_base" }, - "description": "Sample for CompileSuggestion", - "file": "dialogflow_v2beta1_generated_participants_compile_suggestion_async.py", + "description": "Sample for GetKnowledgeBase", + "file": "dialogflow_v2beta1_generated_knowledge_bases_get_knowledge_base_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_CompileSuggestion_async", + "regionTag": "dialogflow_v2beta1_generated_KnowledgeBases_GetKnowledgeBase_async", "segments": [ { - "end": 50, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 50, + "end": 51, "start": 27, "type": "SHORT" }, @@ -13475,43 +13449,47 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 44, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 47, - "start": 45, + "end": 48, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 51, - "start": 48, + "end": 52, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_compile_suggestion_async.py" + "title": "dialogflow_v2beta1_generated_knowledge_bases_get_knowledge_base_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient", - "shortName": "ParticipantsClient" + "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesClient", + "shortName": "KnowledgeBasesClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.compile_suggestion", + "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesClient.get_knowledge_base", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.CompileSuggestion", + "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases.GetKnowledgeBase", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants", - "shortName": "Participants" + "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases", + "shortName": "KnowledgeBases" }, - "shortName": "CompileSuggestion" + "shortName": "GetKnowledgeBase" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.CompileSuggestionRequest" + "type": "google.cloud.dialogflow_v2beta1.types.GetKnowledgeBaseRequest" + }, + { + "name": "name", + "type": "str" }, { "name": "retry", @@ -13526,22 +13504,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.CompileSuggestionResponse", - "shortName": "compile_suggestion" + "resultType": "google.cloud.dialogflow_v2beta1.types.KnowledgeBase", + "shortName": "get_knowledge_base" }, - "description": "Sample for CompileSuggestion", - "file": "dialogflow_v2beta1_generated_participants_compile_suggestion_sync.py", + "description": "Sample for GetKnowledgeBase", + "file": "dialogflow_v2beta1_generated_knowledge_bases_get_knowledge_base_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_CompileSuggestion_sync", + "regionTag": "dialogflow_v2beta1_generated_KnowledgeBases_GetKnowledgeBase_sync", "segments": [ { - "end": 50, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 50, + "end": 51, "start": 27, "type": "SHORT" }, @@ -13551,53 +13529,49 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 44, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 47, - "start": 45, + "end": 48, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 51, - "start": 48, + "end": 52, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_compile_suggestion_sync.py" + "title": "dialogflow_v2beta1_generated_knowledge_bases_get_knowledge_base_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient", - "shortName": "ParticipantsAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesAsyncClient", + "shortName": "KnowledgeBasesAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.create_participant", + "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesAsyncClient.list_knowledge_bases", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.CreateParticipant", + "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases.ListKnowledgeBases", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants", - "shortName": "Participants" + "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases", + "shortName": "KnowledgeBases" }, - "shortName": "CreateParticipant" + "shortName": "ListKnowledgeBases" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.CreateParticipantRequest" + "type": "google.cloud.dialogflow_v2beta1.types.ListKnowledgeBasesRequest" }, { "name": "parent", "type": "str" }, - { - "name": "participant", - "type": "google.cloud.dialogflow_v2beta1.types.Participant" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -13611,22 +13585,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.Participant", - "shortName": "create_participant" + "resultType": "google.cloud.dialogflow_v2beta1.services.knowledge_bases.pagers.ListKnowledgeBasesAsyncPager", + "shortName": "list_knowledge_bases" }, - "description": "Sample for CreateParticipant", - "file": "dialogflow_v2beta1_generated_participants_create_participant_async.py", + "description": "Sample for ListKnowledgeBases", + "file": "dialogflow_v2beta1_generated_knowledge_bases_list_knowledge_bases_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_CreateParticipant_async", + "regionTag": "dialogflow_v2beta1_generated_KnowledgeBases_ListKnowledgeBases_async", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -13646,42 +13620,38 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_create_participant_async.py" + "title": "dialogflow_v2beta1_generated_knowledge_bases_list_knowledge_bases_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient", - "shortName": "ParticipantsClient" + "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesClient", + "shortName": "KnowledgeBasesClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.create_participant", + "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesClient.list_knowledge_bases", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.CreateParticipant", + "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases.ListKnowledgeBases", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants", - "shortName": "Participants" + "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases", + "shortName": "KnowledgeBases" }, - "shortName": "CreateParticipant" + "shortName": "ListKnowledgeBases" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.CreateParticipantRequest" + "type": "google.cloud.dialogflow_v2beta1.types.ListKnowledgeBasesRequest" }, { "name": "parent", "type": "str" }, - { - "name": "participant", - "type": "google.cloud.dialogflow_v2beta1.types.Participant" - }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -13695,22 +13665,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.Participant", - "shortName": "create_participant" + "resultType": "google.cloud.dialogflow_v2beta1.services.knowledge_bases.pagers.ListKnowledgeBasesPager", + "shortName": "list_knowledge_bases" }, - "description": "Sample for CreateParticipant", - "file": "dialogflow_v2beta1_generated_participants_create_participant_sync.py", + "description": "Sample for ListKnowledgeBases", + "file": "dialogflow_v2beta1_generated_knowledge_bases_list_knowledge_bases_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_CreateParticipant_sync", + "regionTag": "dialogflow_v2beta1_generated_KnowledgeBases_ListKnowledgeBases_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -13730,38 +13700,42 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_create_participant_sync.py" + "title": "dialogflow_v2beta1_generated_knowledge_bases_list_knowledge_bases_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient", - "shortName": "ParticipantsAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesAsyncClient", + "shortName": "KnowledgeBasesAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.get_participant", + "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesAsyncClient.update_knowledge_base", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.GetParticipant", + "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases.UpdateKnowledgeBase", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants", - "shortName": "Participants" + "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases", + "shortName": "KnowledgeBases" }, - "shortName": "GetParticipant" + "shortName": "UpdateKnowledgeBase" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.GetParticipantRequest" + "type": "google.cloud.dialogflow_v2beta1.types.UpdateKnowledgeBaseRequest" }, { - "name": "name", - "type": "str" + "name": "knowledge_base", + "type": "google.cloud.dialogflow_v2beta1.types.KnowledgeBase" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" }, { "name": "retry", @@ -13776,22 +13750,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.Participant", - "shortName": "get_participant" + "resultType": "google.cloud.dialogflow_v2beta1.types.KnowledgeBase", + "shortName": "update_knowledge_base" }, - "description": "Sample for GetParticipant", - "file": "dialogflow_v2beta1_generated_participants_get_participant_async.py", + "description": "Sample for UpdateKnowledgeBase", + "file": "dialogflow_v2beta1_generated_knowledge_bases_update_knowledge_base_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_GetParticipant_async", + "regionTag": "dialogflow_v2beta1_generated_KnowledgeBases_UpdateKnowledgeBase_async", "segments": [ { - "end": 51, + "end": 54, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 54, "start": 27, "type": "SHORT" }, @@ -13801,47 +13775,51 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 48, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 51, + "start": 49, "type": "REQUEST_EXECUTION" }, { - "end": 52, - "start": 49, + "end": 55, + "start": 52, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_get_participant_async.py" + "title": "dialogflow_v2beta1_generated_knowledge_bases_update_knowledge_base_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient", - "shortName": "ParticipantsClient" + "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesClient", + "shortName": "KnowledgeBasesClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.get_participant", + "fullName": "google.cloud.dialogflow_v2beta1.KnowledgeBasesClient.update_knowledge_base", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.GetParticipant", + "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases.UpdateKnowledgeBase", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants", - "shortName": "Participants" + "fullName": "google.cloud.dialogflow.v2beta1.KnowledgeBases", + "shortName": "KnowledgeBases" }, - "shortName": "GetParticipant" + "shortName": "UpdateKnowledgeBase" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.GetParticipantRequest" + "type": "google.cloud.dialogflow_v2beta1.types.UpdateKnowledgeBaseRequest" }, { - "name": "name", - "type": "str" + "name": "knowledge_base", + "type": "google.cloud.dialogflow_v2beta1.types.KnowledgeBase" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" }, { "name": "retry", @@ -13856,22 +13834,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.Participant", - "shortName": "get_participant" + "resultType": "google.cloud.dialogflow_v2beta1.types.KnowledgeBase", + "shortName": "update_knowledge_base" }, - "description": "Sample for GetParticipant", - "file": "dialogflow_v2beta1_generated_participants_get_participant_sync.py", + "description": "Sample for UpdateKnowledgeBase", + "file": "dialogflow_v2beta1_generated_knowledge_bases_update_knowledge_base_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_GetParticipant_sync", + "regionTag": "dialogflow_v2beta1_generated_KnowledgeBases_UpdateKnowledgeBase_sync", "segments": [ { - "end": 51, + "end": 54, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 54, "start": 27, "type": "SHORT" }, @@ -13881,22 +13859,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 48, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 51, + "start": 49, "type": "REQUEST_EXECUTION" }, { - "end": 52, - "start": 49, + "end": 55, + "start": 52, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_get_participant_sync.py" + "title": "dialogflow_v2beta1_generated_knowledge_bases_update_knowledge_base_sync.py" }, { "canonical": true, @@ -13906,24 +13884,36 @@ "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient", "shortName": "ParticipantsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.list_participants", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.analyze_content", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.ListParticipants", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.AnalyzeContent", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Participants", "shortName": "Participants" }, - "shortName": "ListParticipants" + "shortName": "AnalyzeContent" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.ListParticipantsRequest" + "type": "google.cloud.dialogflow_v2beta1.types.AnalyzeContentRequest" }, { - "name": "parent", + "name": "participant", "type": "str" }, + { + "name": "text_input", + "type": "google.cloud.dialogflow_v2beta1.types.TextInput" + }, + { + "name": "audio_input", + "type": "google.cloud.dialogflow_v2beta1.types.AudioInput" + }, + { + "name": "event_input", + "type": "google.cloud.dialogflow_v2beta1.types.EventInput" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -13937,22 +13927,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.services.participants.pagers.ListParticipantsAsyncPager", - "shortName": "list_participants" + "resultType": "google.cloud.dialogflow_v2beta1.types.AnalyzeContentResponse", + "shortName": "analyze_content" }, - "description": "Sample for ListParticipants", - "file": "dialogflow_v2beta1_generated_participants_list_participants_async.py", + "description": "Sample for AnalyzeContent", + "file": "dialogflow_v2beta1_generated_participants_analyze_content_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_ListParticipants_async", + "regionTag": "dialogflow_v2beta1_generated_Participants_AnalyzeContent_async", "segments": [ { - "end": 52, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 51, "start": 27, "type": "SHORT" }, @@ -13972,12 +13962,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 53, + "end": 52, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_list_participants_async.py" + "title": "dialogflow_v2beta1_generated_participants_analyze_content_async.py" }, { "canonical": true, @@ -13986,24 +13976,36 @@ "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient", "shortName": "ParticipantsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.list_participants", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.analyze_content", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.ListParticipants", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.AnalyzeContent", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Participants", "shortName": "Participants" }, - "shortName": "ListParticipants" + "shortName": "AnalyzeContent" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.ListParticipantsRequest" + "type": "google.cloud.dialogflow_v2beta1.types.AnalyzeContentRequest" }, { - "name": "parent", + "name": "participant", "type": "str" }, + { + "name": "text_input", + "type": "google.cloud.dialogflow_v2beta1.types.TextInput" + }, + { + "name": "audio_input", + "type": "google.cloud.dialogflow_v2beta1.types.AudioInput" + }, + { + "name": "event_input", + "type": "google.cloud.dialogflow_v2beta1.types.EventInput" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -14017,22 +14019,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.services.participants.pagers.ListParticipantsPager", - "shortName": "list_participants" + "resultType": "google.cloud.dialogflow_v2beta1.types.AnalyzeContentResponse", + "shortName": "analyze_content" }, - "description": "Sample for ListParticipants", - "file": "dialogflow_v2beta1_generated_participants_list_participants_sync.py", + "description": "Sample for AnalyzeContent", + "file": "dialogflow_v2beta1_generated_participants_analyze_content_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_ListParticipants_sync", + "regionTag": "dialogflow_v2beta1_generated_Participants_AnalyzeContent_sync", "segments": [ { - "end": 52, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 51, "start": 27, "type": "SHORT" }, @@ -14052,12 +14054,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 53, + "end": 52, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_list_participants_sync.py" + "title": "dialogflow_v2beta1_generated_participants_analyze_content_sync.py" }, { "canonical": true, @@ -14067,19 +14069,19 @@ "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient", "shortName": "ParticipantsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.list_suggestions", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.bidi_streaming_analyze_content", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.ListSuggestions", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.BidiStreamingAnalyzeContent", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Participants", "shortName": "Participants" }, - "shortName": "ListSuggestions" + "shortName": "BidiStreamingAnalyzeContent" }, "parameters": [ { - "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.ListSuggestionsRequest" + "name": "requests", + "type": "Iterator[google.cloud.dialogflow_v2beta1.types.BidiStreamingAnalyzeContentRequest]" }, { "name": "retry", @@ -14094,22 +14096,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.services.participants.pagers.ListSuggestionsAsyncPager", - "shortName": "list_suggestions" + "resultType": "Iterable[google.cloud.dialogflow_v2beta1.types.BidiStreamingAnalyzeContentResponse]", + "shortName": "bidi_streaming_analyze_content" }, - "description": "Sample for ListSuggestions", - "file": "dialogflow_v2beta1_generated_participants_list_suggestions_async.py", + "description": "Sample for BidiStreamingAnalyzeContent", + "file": "dialogflow_v2beta1_generated_participants_bidi_streaming_analyze_content_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_ListSuggestions_async", + "regionTag": "dialogflow_v2beta1_generated_Participants_BidiStreamingAnalyzeContent_async", "segments": [ { - "end": 51, + "end": 69, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 69, "start": 27, "type": "SHORT" }, @@ -14119,22 +14121,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 44, + "end": 62, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 47, - "start": 45, + "end": 65, + "start": 63, "type": "REQUEST_EXECUTION" }, { - "end": 52, - "start": 48, + "end": 70, + "start": 66, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_list_suggestions_async.py" + "title": "dialogflow_v2beta1_generated_participants_bidi_streaming_analyze_content_async.py" }, { "canonical": true, @@ -14143,19 +14145,19 @@ "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient", "shortName": "ParticipantsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.list_suggestions", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.bidi_streaming_analyze_content", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.ListSuggestions", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.BidiStreamingAnalyzeContent", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Participants", "shortName": "Participants" }, - "shortName": "ListSuggestions" + "shortName": "BidiStreamingAnalyzeContent" }, "parameters": [ { - "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.ListSuggestionsRequest" + "name": "requests", + "type": "Iterator[google.cloud.dialogflow_v2beta1.types.BidiStreamingAnalyzeContentRequest]" }, { "name": "retry", @@ -14170,22 +14172,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.services.participants.pagers.ListSuggestionsPager", - "shortName": "list_suggestions" + "resultType": "Iterable[google.cloud.dialogflow_v2beta1.types.BidiStreamingAnalyzeContentResponse]", + "shortName": "bidi_streaming_analyze_content" }, - "description": "Sample for ListSuggestions", - "file": "dialogflow_v2beta1_generated_participants_list_suggestions_sync.py", + "description": "Sample for BidiStreamingAnalyzeContent", + "file": "dialogflow_v2beta1_generated_participants_bidi_streaming_analyze_content_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_ListSuggestions_sync", + "regionTag": "dialogflow_v2beta1_generated_Participants_BidiStreamingAnalyzeContent_sync", "segments": [ { - "end": 51, + "end": 69, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 69, "start": 27, "type": "SHORT" }, @@ -14195,22 +14197,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 44, + "end": 62, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 47, - "start": 45, + "end": 65, + "start": 63, "type": "REQUEST_EXECUTION" }, { - "end": 52, - "start": 48, + "end": 70, + "start": 66, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_list_suggestions_sync.py" + "title": "dialogflow_v2beta1_generated_participants_bidi_streaming_analyze_content_sync.py" }, { "canonical": true, @@ -14220,19 +14222,19 @@ "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient", "shortName": "ParticipantsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.streaming_analyze_content", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.compile_suggestion", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.StreamingAnalyzeContent", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.CompileSuggestion", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Participants", "shortName": "Participants" }, - "shortName": "StreamingAnalyzeContent" + "shortName": "CompileSuggestion" }, "parameters": [ { - "name": "requests", - "type": "Iterator[google.cloud.dialogflow_v2beta1.types.StreamingAnalyzeContentRequest]" + "name": "request", + "type": "google.cloud.dialogflow_v2beta1.types.CompileSuggestionRequest" }, { "name": "retry", @@ -14247,22 +14249,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "Iterable[google.cloud.dialogflow_v2beta1.types.StreamingAnalyzeContentResponse]", - "shortName": "streaming_analyze_content" + "resultType": "google.cloud.dialogflow_v2beta1.types.CompileSuggestionResponse", + "shortName": "compile_suggestion" }, - "description": "Sample for StreamingAnalyzeContent", - "file": "dialogflow_v2beta1_generated_participants_streaming_analyze_content_async.py", + "description": "Sample for CompileSuggestion", + "file": "dialogflow_v2beta1_generated_participants_compile_suggestion_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_StreamingAnalyzeContent_async", + "regionTag": "dialogflow_v2beta1_generated_Participants_CompileSuggestion_async", "segments": [ { - "end": 69, + "end": 50, "start": 27, "type": "FULL" }, { - "end": 69, + "end": 50, "start": 27, "type": "SHORT" }, @@ -14272,22 +14274,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 62, + "end": 44, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 65, - "start": 63, + "end": 47, + "start": 45, "type": "REQUEST_EXECUTION" }, { - "end": 70, - "start": 66, + "end": 51, + "start": 48, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_streaming_analyze_content_async.py" + "title": "dialogflow_v2beta1_generated_participants_compile_suggestion_async.py" }, { "canonical": true, @@ -14296,19 +14298,19 @@ "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient", "shortName": "ParticipantsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.streaming_analyze_content", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.compile_suggestion", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.StreamingAnalyzeContent", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.CompileSuggestion", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Participants", "shortName": "Participants" }, - "shortName": "StreamingAnalyzeContent" + "shortName": "CompileSuggestion" }, "parameters": [ { - "name": "requests", - "type": "Iterator[google.cloud.dialogflow_v2beta1.types.StreamingAnalyzeContentRequest]" + "name": "request", + "type": "google.cloud.dialogflow_v2beta1.types.CompileSuggestionRequest" }, { "name": "retry", @@ -14323,22 +14325,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "Iterable[google.cloud.dialogflow_v2beta1.types.StreamingAnalyzeContentResponse]", - "shortName": "streaming_analyze_content" + "resultType": "google.cloud.dialogflow_v2beta1.types.CompileSuggestionResponse", + "shortName": "compile_suggestion" }, - "description": "Sample for StreamingAnalyzeContent", - "file": "dialogflow_v2beta1_generated_participants_streaming_analyze_content_sync.py", + "description": "Sample for CompileSuggestion", + "file": "dialogflow_v2beta1_generated_participants_compile_suggestion_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_StreamingAnalyzeContent_sync", + "regionTag": "dialogflow_v2beta1_generated_Participants_CompileSuggestion_sync", "segments": [ { - "end": 69, + "end": 50, "start": 27, "type": "FULL" }, { - "end": 69, + "end": 50, "start": 27, "type": "SHORT" }, @@ -14348,22 +14350,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 62, + "end": 44, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 65, - "start": 63, + "end": 47, + "start": 45, "type": "REQUEST_EXECUTION" }, { - "end": 70, - "start": 66, + "end": 51, + "start": 48, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_streaming_analyze_content_sync.py" + "title": "dialogflow_v2beta1_generated_participants_compile_suggestion_sync.py" }, { "canonical": true, @@ -14373,24 +14375,28 @@ "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient", "shortName": "ParticipantsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.suggest_articles", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.create_participant", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.SuggestArticles", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.CreateParticipant", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Participants", "shortName": "Participants" }, - "shortName": "SuggestArticles" + "shortName": "CreateParticipant" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.SuggestArticlesRequest" + "type": "google.cloud.dialogflow_v2beta1.types.CreateParticipantRequest" }, { "name": "parent", "type": "str" }, + { + "name": "participant", + "type": "google.cloud.dialogflow_v2beta1.types.Participant" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -14404,14 +14410,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.SuggestArticlesResponse", - "shortName": "suggest_articles" + "resultType": "google.cloud.dialogflow_v2beta1.types.Participant", + "shortName": "create_participant" }, - "description": "Sample for SuggestArticles", - "file": "dialogflow_v2beta1_generated_participants_suggest_articles_async.py", + "description": "Sample for CreateParticipant", + "file": "dialogflow_v2beta1_generated_participants_create_participant_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_SuggestArticles_async", + "regionTag": "dialogflow_v2beta1_generated_Participants_CreateParticipant_async", "segments": [ { "end": 51, @@ -14444,7 +14450,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_suggest_articles_async.py" + "title": "dialogflow_v2beta1_generated_participants_create_participant_async.py" }, { "canonical": true, @@ -14453,24 +14459,28 @@ "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient", "shortName": "ParticipantsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.suggest_articles", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.create_participant", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.SuggestArticles", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.CreateParticipant", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Participants", "shortName": "Participants" }, - "shortName": "SuggestArticles" + "shortName": "CreateParticipant" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.SuggestArticlesRequest" + "type": "google.cloud.dialogflow_v2beta1.types.CreateParticipantRequest" }, { "name": "parent", "type": "str" }, + { + "name": "participant", + "type": "google.cloud.dialogflow_v2beta1.types.Participant" + }, { "name": "retry", "type": "google.api_core.retry.Retry" @@ -14484,14 +14494,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.SuggestArticlesResponse", - "shortName": "suggest_articles" + "resultType": "google.cloud.dialogflow_v2beta1.types.Participant", + "shortName": "create_participant" }, - "description": "Sample for SuggestArticles", - "file": "dialogflow_v2beta1_generated_participants_suggest_articles_sync.py", + "description": "Sample for CreateParticipant", + "file": "dialogflow_v2beta1_generated_participants_create_participant_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_SuggestArticles_sync", + "regionTag": "dialogflow_v2beta1_generated_Participants_CreateParticipant_sync", "segments": [ { "end": 51, @@ -14524,7 +14534,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_suggest_articles_sync.py" + "title": "dialogflow_v2beta1_generated_participants_create_participant_sync.py" }, { "canonical": true, @@ -14534,22 +14544,22 @@ "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient", "shortName": "ParticipantsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.suggest_faq_answers", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.get_participant", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.SuggestFaqAnswers", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.GetParticipant", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Participants", "shortName": "Participants" }, - "shortName": "SuggestFaqAnswers" + "shortName": "GetParticipant" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.SuggestFaqAnswersRequest" + "type": "google.cloud.dialogflow_v2beta1.types.GetParticipantRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, { @@ -14565,14 +14575,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.SuggestFaqAnswersResponse", - "shortName": "suggest_faq_answers" + "resultType": "google.cloud.dialogflow_v2beta1.types.Participant", + "shortName": "get_participant" }, - "description": "Sample for SuggestFaqAnswers", - "file": "dialogflow_v2beta1_generated_participants_suggest_faq_answers_async.py", + "description": "Sample for GetParticipant", + "file": "dialogflow_v2beta1_generated_participants_get_participant_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_SuggestFaqAnswers_async", + "regionTag": "dialogflow_v2beta1_generated_Participants_GetParticipant_async", "segments": [ { "end": 51, @@ -14605,7 +14615,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_suggest_faq_answers_async.py" + "title": "dialogflow_v2beta1_generated_participants_get_participant_async.py" }, { "canonical": true, @@ -14614,22 +14624,22 @@ "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient", "shortName": "ParticipantsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.suggest_faq_answers", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.get_participant", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.SuggestFaqAnswers", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.GetParticipant", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Participants", "shortName": "Participants" }, - "shortName": "SuggestFaqAnswers" + "shortName": "GetParticipant" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.SuggestFaqAnswersRequest" + "type": "google.cloud.dialogflow_v2beta1.types.GetParticipantRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, { @@ -14645,14 +14655,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.SuggestFaqAnswersResponse", - "shortName": "suggest_faq_answers" + "resultType": "google.cloud.dialogflow_v2beta1.types.Participant", + "shortName": "get_participant" }, - "description": "Sample for SuggestFaqAnswers", - "file": "dialogflow_v2beta1_generated_participants_suggest_faq_answers_sync.py", + "description": "Sample for GetParticipant", + "file": "dialogflow_v2beta1_generated_participants_get_participant_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_SuggestFaqAnswers_sync", + "regionTag": "dialogflow_v2beta1_generated_Participants_GetParticipant_sync", "segments": [ { "end": 51, @@ -14685,7 +14695,7 @@ "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_suggest_faq_answers_sync.py" + "title": "dialogflow_v2beta1_generated_participants_get_participant_sync.py" }, { "canonical": true, @@ -14695,19 +14705,23 @@ "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient", "shortName": "ParticipantsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.suggest_knowledge_assist", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.list_participants", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.SuggestKnowledgeAssist", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.ListParticipants", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Participants", "shortName": "Participants" }, - "shortName": "SuggestKnowledgeAssist" + "shortName": "ListParticipants" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.SuggestKnowledgeAssistRequest" + "type": "google.cloud.dialogflow_v2beta1.types.ListParticipantsRequest" + }, + { + "name": "parent", + "type": "str" }, { "name": "retry", @@ -14722,22 +14736,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.SuggestKnowledgeAssistResponse", - "shortName": "suggest_knowledge_assist" + "resultType": "google.cloud.dialogflow_v2beta1.services.participants.pagers.ListParticipantsAsyncPager", + "shortName": "list_participants" }, - "description": "Sample for SuggestKnowledgeAssist", - "file": "dialogflow_v2beta1_generated_participants_suggest_knowledge_assist_async.py", + "description": "Sample for ListParticipants", + "file": "dialogflow_v2beta1_generated_participants_list_participants_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_SuggestKnowledgeAssist_async", + "regionTag": "dialogflow_v2beta1_generated_Participants_ListParticipants_async", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -14757,12 +14771,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_suggest_knowledge_assist_async.py" + "title": "dialogflow_v2beta1_generated_participants_list_participants_async.py" }, { "canonical": true, @@ -14771,19 +14785,23 @@ "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient", "shortName": "ParticipantsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.suggest_knowledge_assist", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.list_participants", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.SuggestKnowledgeAssist", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.ListParticipants", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Participants", "shortName": "Participants" }, - "shortName": "SuggestKnowledgeAssist" + "shortName": "ListParticipants" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.SuggestKnowledgeAssistRequest" + "type": "google.cloud.dialogflow_v2beta1.types.ListParticipantsRequest" + }, + { + "name": "parent", + "type": "str" }, { "name": "retry", @@ -14798,22 +14816,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.SuggestKnowledgeAssistResponse", - "shortName": "suggest_knowledge_assist" + "resultType": "google.cloud.dialogflow_v2beta1.services.participants.pagers.ListParticipantsPager", + "shortName": "list_participants" }, - "description": "Sample for SuggestKnowledgeAssist", - "file": "dialogflow_v2beta1_generated_participants_suggest_knowledge_assist_sync.py", + "description": "Sample for ListParticipants", + "file": "dialogflow_v2beta1_generated_participants_list_participants_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_SuggestKnowledgeAssist_sync", + "regionTag": "dialogflow_v2beta1_generated_Participants_ListParticipants_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -14833,12 +14851,12 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_suggest_knowledge_assist_sync.py" + "title": "dialogflow_v2beta1_generated_participants_list_participants_sync.py" }, { "canonical": true, @@ -14848,23 +14866,19 @@ "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient", "shortName": "ParticipantsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.suggest_smart_replies", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.list_suggestions", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.SuggestSmartReplies", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.ListSuggestions", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Participants", "shortName": "Participants" }, - "shortName": "SuggestSmartReplies" + "shortName": "ListSuggestions" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.SuggestSmartRepliesRequest" - }, - { - "name": "parent", - "type": "str" + "type": "google.cloud.dialogflow_v2beta1.types.ListSuggestionsRequest" }, { "name": "retry", @@ -14879,14 +14893,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.SuggestSmartRepliesResponse", - "shortName": "suggest_smart_replies" + "resultType": "google.cloud.dialogflow_v2beta1.services.participants.pagers.ListSuggestionsAsyncPager", + "shortName": "list_suggestions" }, - "description": "Sample for SuggestSmartReplies", - "file": "dialogflow_v2beta1_generated_participants_suggest_smart_replies_async.py", + "description": "Sample for ListSuggestions", + "file": "dialogflow_v2beta1_generated_participants_list_suggestions_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_SuggestSmartReplies_async", + "regionTag": "dialogflow_v2beta1_generated_Participants_ListSuggestions_async", "segments": [ { "end": 51, @@ -14904,22 +14918,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 44, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 47, + "start": 45, "type": "REQUEST_EXECUTION" }, { "end": 52, - "start": 49, + "start": 48, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_suggest_smart_replies_async.py" + "title": "dialogflow_v2beta1_generated_participants_list_suggestions_async.py" }, { "canonical": true, @@ -14928,23 +14942,19 @@ "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient", "shortName": "ParticipantsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.suggest_smart_replies", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.list_suggestions", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.SuggestSmartReplies", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.ListSuggestions", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Participants", "shortName": "Participants" }, - "shortName": "SuggestSmartReplies" + "shortName": "ListSuggestions" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.SuggestSmartRepliesRequest" - }, - { - "name": "parent", - "type": "str" + "type": "google.cloud.dialogflow_v2beta1.types.ListSuggestionsRequest" }, { "name": "retry", @@ -14959,14 +14969,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.SuggestSmartRepliesResponse", - "shortName": "suggest_smart_replies" + "resultType": "google.cloud.dialogflow_v2beta1.services.participants.pagers.ListSuggestionsPager", + "shortName": "list_suggestions" }, - "description": "Sample for SuggestSmartReplies", - "file": "dialogflow_v2beta1_generated_participants_suggest_smart_replies_sync.py", + "description": "Sample for ListSuggestions", + "file": "dialogflow_v2beta1_generated_participants_list_suggestions_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_SuggestSmartReplies_sync", + "regionTag": "dialogflow_v2beta1_generated_Participants_ListSuggestions_sync", "segments": [ { "end": 51, @@ -14984,22 +14994,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 44, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 47, + "start": 45, "type": "REQUEST_EXECUTION" }, { "end": 52, - "start": 49, + "start": 48, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_suggest_smart_replies_sync.py" + "title": "dialogflow_v2beta1_generated_participants_list_suggestions_sync.py" }, { "canonical": true, @@ -15009,27 +15019,19 @@ "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient", "shortName": "ParticipantsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.update_participant", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.streaming_analyze_content", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.UpdateParticipant", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.StreamingAnalyzeContent", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Participants", "shortName": "Participants" }, - "shortName": "UpdateParticipant" + "shortName": "StreamingAnalyzeContent" }, "parameters": [ { - "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.UpdateParticipantRequest" - }, - { - "name": "participant", - "type": "google.cloud.dialogflow_v2beta1.types.Participant" - }, - { - "name": "update_mask", - "type": "google.protobuf.field_mask_pb2.FieldMask" + "name": "requests", + "type": "Iterator[google.cloud.dialogflow_v2beta1.types.StreamingAnalyzeContentRequest]" }, { "name": "retry", @@ -15044,22 +15046,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.Participant", - "shortName": "update_participant" + "resultType": "Iterable[google.cloud.dialogflow_v2beta1.types.StreamingAnalyzeContentResponse]", + "shortName": "streaming_analyze_content" }, - "description": "Sample for UpdateParticipant", - "file": "dialogflow_v2beta1_generated_participants_update_participant_async.py", + "description": "Sample for StreamingAnalyzeContent", + "file": "dialogflow_v2beta1_generated_participants_streaming_analyze_content_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_UpdateParticipant_async", + "regionTag": "dialogflow_v2beta1_generated_Participants_StreamingAnalyzeContent_async", "segments": [ { - "end": 50, + "end": 69, "start": 27, "type": "FULL" }, { - "end": 50, + "end": 69, "start": 27, "type": "SHORT" }, @@ -15069,22 +15071,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 44, + "end": 62, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 47, - "start": 45, + "end": 65, + "start": 63, "type": "REQUEST_EXECUTION" }, { - "end": 51, - "start": 48, + "end": 70, + "start": 66, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_update_participant_async.py" + "title": "dialogflow_v2beta1_generated_participants_streaming_analyze_content_async.py" }, { "canonical": true, @@ -15093,27 +15095,19 @@ "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient", "shortName": "ParticipantsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.update_participant", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.streaming_analyze_content", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Participants.UpdateParticipant", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.StreamingAnalyzeContent", "service": { "fullName": "google.cloud.dialogflow.v2beta1.Participants", "shortName": "Participants" }, - "shortName": "UpdateParticipant" + "shortName": "StreamingAnalyzeContent" }, "parameters": [ { - "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.UpdateParticipantRequest" - }, - { - "name": "participant", - "type": "google.cloud.dialogflow_v2beta1.types.Participant" - }, - { - "name": "update_mask", - "type": "google.protobuf.field_mask_pb2.FieldMask" + "name": "requests", + "type": "Iterator[google.cloud.dialogflow_v2beta1.types.StreamingAnalyzeContentRequest]" }, { "name": "retry", @@ -15128,22 +15122,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.Participant", - "shortName": "update_participant" + "resultType": "Iterable[google.cloud.dialogflow_v2beta1.types.StreamingAnalyzeContentResponse]", + "shortName": "streaming_analyze_content" }, - "description": "Sample for UpdateParticipant", - "file": "dialogflow_v2beta1_generated_participants_update_participant_sync.py", + "description": "Sample for StreamingAnalyzeContent", + "file": "dialogflow_v2beta1_generated_participants_streaming_analyze_content_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Participants_UpdateParticipant_sync", + "regionTag": "dialogflow_v2beta1_generated_Participants_StreamingAnalyzeContent_sync", "segments": [ { - "end": 50, + "end": 69, "start": 27, "type": "FULL" }, { - "end": 50, + "end": 69, "start": 27, "type": "SHORT" }, @@ -15153,47 +15147,47 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 44, + "end": 62, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 47, - "start": 45, + "end": 65, + "start": 63, "type": "REQUEST_EXECUTION" }, { - "end": 51, - "start": 48, + "end": 70, + "start": 66, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_participants_update_participant_sync.py" + "title": "dialogflow_v2beta1_generated_participants_streaming_analyze_content_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersAsyncClient", - "shortName": "PhoneNumbersAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient", + "shortName": "ParticipantsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersAsyncClient.delete_phone_number", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.suggest_articles", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers.DeletePhoneNumber", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.SuggestArticles", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers", - "shortName": "PhoneNumbers" + "fullName": "google.cloud.dialogflow.v2beta1.Participants", + "shortName": "Participants" }, - "shortName": "DeletePhoneNumber" + "shortName": "SuggestArticles" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.DeletePhoneNumberRequest" + "type": "google.cloud.dialogflow_v2beta1.types.SuggestArticlesRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -15209,14 +15203,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.PhoneNumber", - "shortName": "delete_phone_number" + "resultType": "google.cloud.dialogflow_v2beta1.types.SuggestArticlesResponse", + "shortName": "suggest_articles" }, - "description": "Sample for DeletePhoneNumber", - "file": "dialogflow_v2beta1_generated_phone_numbers_delete_phone_number_async.py", + "description": "Sample for SuggestArticles", + "file": "dialogflow_v2beta1_generated_participants_suggest_articles_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_PhoneNumbers_DeletePhoneNumber_async", + "regionTag": "dialogflow_v2beta1_generated_Participants_SuggestArticles_async", "segments": [ { "end": 51, @@ -15249,31 +15243,31 @@ "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_phone_numbers_delete_phone_number_async.py" + "title": "dialogflow_v2beta1_generated_participants_suggest_articles_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersClient", - "shortName": "PhoneNumbersClient" + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient", + "shortName": "ParticipantsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersClient.delete_phone_number", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.suggest_articles", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers.DeletePhoneNumber", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.SuggestArticles", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers", - "shortName": "PhoneNumbers" + "fullName": "google.cloud.dialogflow.v2beta1.Participants", + "shortName": "Participants" }, - "shortName": "DeletePhoneNumber" + "shortName": "SuggestArticles" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.DeletePhoneNumberRequest" + "type": "google.cloud.dialogflow_v2beta1.types.SuggestArticlesRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -15289,14 +15283,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.PhoneNumber", - "shortName": "delete_phone_number" + "resultType": "google.cloud.dialogflow_v2beta1.types.SuggestArticlesResponse", + "shortName": "suggest_articles" }, - "description": "Sample for DeletePhoneNumber", - "file": "dialogflow_v2beta1_generated_phone_numbers_delete_phone_number_sync.py", + "description": "Sample for SuggestArticles", + "file": "dialogflow_v2beta1_generated_participants_suggest_articles_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_PhoneNumbers_DeletePhoneNumber_sync", + "regionTag": "dialogflow_v2beta1_generated_Participants_SuggestArticles_sync", "segments": [ { "end": 51, @@ -15329,29 +15323,29 @@ "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_phone_numbers_delete_phone_number_sync.py" + "title": "dialogflow_v2beta1_generated_participants_suggest_articles_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersAsyncClient", - "shortName": "PhoneNumbersAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient", + "shortName": "ParticipantsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersAsyncClient.list_phone_numbers", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.suggest_faq_answers", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers.ListPhoneNumbers", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.SuggestFaqAnswers", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers", - "shortName": "PhoneNumbers" + "fullName": "google.cloud.dialogflow.v2beta1.Participants", + "shortName": "Participants" }, - "shortName": "ListPhoneNumbers" + "shortName": "SuggestFaqAnswers" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.ListPhoneNumbersRequest" + "type": "google.cloud.dialogflow_v2beta1.types.SuggestFaqAnswersRequest" }, { "name": "parent", @@ -15370,22 +15364,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.services.phone_numbers.pagers.ListPhoneNumbersAsyncPager", - "shortName": "list_phone_numbers" + "resultType": "google.cloud.dialogflow_v2beta1.types.SuggestFaqAnswersResponse", + "shortName": "suggest_faq_answers" }, - "description": "Sample for ListPhoneNumbers", - "file": "dialogflow_v2beta1_generated_phone_numbers_list_phone_numbers_async.py", + "description": "Sample for SuggestFaqAnswers", + "file": "dialogflow_v2beta1_generated_participants_suggest_faq_answers_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_PhoneNumbers_ListPhoneNumbers_async", + "regionTag": "dialogflow_v2beta1_generated_Participants_SuggestFaqAnswers_async", "segments": [ { - "end": 52, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 51, "start": 27, "type": "SHORT" }, @@ -15405,33 +15399,33 @@ "type": "REQUEST_EXECUTION" }, { - "end": 53, + "end": 52, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_phone_numbers_list_phone_numbers_async.py" + "title": "dialogflow_v2beta1_generated_participants_suggest_faq_answers_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersClient", - "shortName": "PhoneNumbersClient" + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient", + "shortName": "ParticipantsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersClient.list_phone_numbers", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.suggest_faq_answers", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers.ListPhoneNumbers", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.SuggestFaqAnswers", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers", - "shortName": "PhoneNumbers" + "fullName": "google.cloud.dialogflow.v2beta1.Participants", + "shortName": "Participants" }, - "shortName": "ListPhoneNumbers" + "shortName": "SuggestFaqAnswers" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.ListPhoneNumbersRequest" + "type": "google.cloud.dialogflow_v2beta1.types.SuggestFaqAnswersRequest" }, { "name": "parent", @@ -15450,22 +15444,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.services.phone_numbers.pagers.ListPhoneNumbersPager", - "shortName": "list_phone_numbers" + "resultType": "google.cloud.dialogflow_v2beta1.types.SuggestFaqAnswersResponse", + "shortName": "suggest_faq_answers" }, - "description": "Sample for ListPhoneNumbers", - "file": "dialogflow_v2beta1_generated_phone_numbers_list_phone_numbers_sync.py", + "description": "Sample for SuggestFaqAnswers", + "file": "dialogflow_v2beta1_generated_participants_suggest_faq_answers_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_PhoneNumbers_ListPhoneNumbers_sync", + "regionTag": "dialogflow_v2beta1_generated_Participants_SuggestFaqAnswers_sync", "segments": [ { - "end": 52, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 51, "start": 27, "type": "SHORT" }, @@ -15485,38 +15479,34 @@ "type": "REQUEST_EXECUTION" }, { - "end": 53, + "end": 52, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_phone_numbers_list_phone_numbers_sync.py" + "title": "dialogflow_v2beta1_generated_participants_suggest_faq_answers_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersAsyncClient", - "shortName": "PhoneNumbersAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient", + "shortName": "ParticipantsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersAsyncClient.undelete_phone_number", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.suggest_knowledge_assist", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers.UndeletePhoneNumber", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.SuggestKnowledgeAssist", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers", - "shortName": "PhoneNumbers" + "fullName": "google.cloud.dialogflow.v2beta1.Participants", + "shortName": "Participants" }, - "shortName": "UndeletePhoneNumber" + "shortName": "SuggestKnowledgeAssist" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.UndeletePhoneNumberRequest" - }, - { - "name": "name", - "type": "str" + "type": "google.cloud.dialogflow_v2beta1.types.SuggestKnowledgeAssistRequest" }, { "name": "retry", @@ -15531,14 +15521,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.PhoneNumber", - "shortName": "undelete_phone_number" + "resultType": "google.cloud.dialogflow_v2beta1.types.SuggestKnowledgeAssistResponse", + "shortName": "suggest_knowledge_assist" }, - "description": "Sample for UndeletePhoneNumber", - "file": "dialogflow_v2beta1_generated_phone_numbers_undelete_phone_number_async.py", + "description": "Sample for SuggestKnowledgeAssist", + "file": "dialogflow_v2beta1_generated_participants_suggest_knowledge_assist_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_PhoneNumbers_UndeletePhoneNumber_async", + "regionTag": "dialogflow_v2beta1_generated_Participants_SuggestKnowledgeAssist_async", "segments": [ { "end": 51, @@ -15571,32 +15561,28 @@ "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_phone_numbers_undelete_phone_number_async.py" + "title": "dialogflow_v2beta1_generated_participants_suggest_knowledge_assist_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersClient", - "shortName": "PhoneNumbersClient" + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient", + "shortName": "ParticipantsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersClient.undelete_phone_number", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.suggest_knowledge_assist", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers.UndeletePhoneNumber", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.SuggestKnowledgeAssist", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers", - "shortName": "PhoneNumbers" + "fullName": "google.cloud.dialogflow.v2beta1.Participants", + "shortName": "Participants" }, - "shortName": "UndeletePhoneNumber" + "shortName": "SuggestKnowledgeAssist" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.UndeletePhoneNumberRequest" - }, - { - "name": "name", - "type": "str" + "type": "google.cloud.dialogflow_v2beta1.types.SuggestKnowledgeAssistRequest" }, { "name": "retry", @@ -15611,14 +15597,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.PhoneNumber", - "shortName": "undelete_phone_number" + "resultType": "google.cloud.dialogflow_v2beta1.types.SuggestKnowledgeAssistResponse", + "shortName": "suggest_knowledge_assist" }, - "description": "Sample for UndeletePhoneNumber", - "file": "dialogflow_v2beta1_generated_phone_numbers_undelete_phone_number_sync.py", + "description": "Sample for SuggestKnowledgeAssist", + "file": "dialogflow_v2beta1_generated_participants_suggest_knowledge_assist_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_PhoneNumbers_UndeletePhoneNumber_sync", + "regionTag": "dialogflow_v2beta1_generated_Participants_SuggestKnowledgeAssist_sync", "segments": [ { "end": 51, @@ -15651,37 +15637,33 @@ "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_phone_numbers_undelete_phone_number_sync.py" + "title": "dialogflow_v2beta1_generated_participants_suggest_knowledge_assist_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersAsyncClient", - "shortName": "PhoneNumbersAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient", + "shortName": "ParticipantsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersAsyncClient.update_phone_number", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.suggest_smart_replies", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers.UpdatePhoneNumber", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.SuggestSmartReplies", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers", - "shortName": "PhoneNumbers" + "fullName": "google.cloud.dialogflow.v2beta1.Participants", + "shortName": "Participants" }, - "shortName": "UpdatePhoneNumber" + "shortName": "SuggestSmartReplies" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.UpdatePhoneNumberRequest" - }, - { - "name": "phone_number", - "type": "google.cloud.dialogflow_v2beta1.types.PhoneNumber" + "type": "google.cloud.dialogflow_v2beta1.types.SuggestSmartRepliesRequest" }, { - "name": "update_mask", - "type": "google.protobuf.field_mask_pb2.FieldMask" + "name": "parent", + "type": "str" }, { "name": "retry", @@ -15696,22 +15678,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.PhoneNumber", - "shortName": "update_phone_number" + "resultType": "google.cloud.dialogflow_v2beta1.types.SuggestSmartRepliesResponse", + "shortName": "suggest_smart_replies" }, - "description": "Sample for UpdatePhoneNumber", - "file": "dialogflow_v2beta1_generated_phone_numbers_update_phone_number_async.py", + "description": "Sample for SuggestSmartReplies", + "file": "dialogflow_v2beta1_generated_participants_suggest_smart_replies_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_PhoneNumbers_UpdatePhoneNumber_async", + "regionTag": "dialogflow_v2beta1_generated_Participants_SuggestSmartReplies_async", "segments": [ { - "end": 50, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 50, + "end": 51, "start": 27, "type": "SHORT" }, @@ -15721,51 +15703,47 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 44, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 47, - "start": 45, + "end": 48, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 51, - "start": 48, + "end": 52, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_phone_numbers_update_phone_number_async.py" + "title": "dialogflow_v2beta1_generated_participants_suggest_smart_replies_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersClient", - "shortName": "PhoneNumbersClient" + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient", + "shortName": "ParticipantsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersClient.update_phone_number", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.suggest_smart_replies", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers.UpdatePhoneNumber", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.SuggestSmartReplies", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers", - "shortName": "PhoneNumbers" + "fullName": "google.cloud.dialogflow.v2beta1.Participants", + "shortName": "Participants" }, - "shortName": "UpdatePhoneNumber" + "shortName": "SuggestSmartReplies" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.UpdatePhoneNumberRequest" - }, - { - "name": "phone_number", - "type": "google.cloud.dialogflow_v2beta1.types.PhoneNumber" + "type": "google.cloud.dialogflow_v2beta1.types.SuggestSmartRepliesRequest" }, { - "name": "update_mask", - "type": "google.protobuf.field_mask_pb2.FieldMask" + "name": "parent", + "type": "str" }, { "name": "retry", @@ -15780,22 +15758,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.PhoneNumber", - "shortName": "update_phone_number" + "resultType": "google.cloud.dialogflow_v2beta1.types.SuggestSmartRepliesResponse", + "shortName": "suggest_smart_replies" }, - "description": "Sample for UpdatePhoneNumber", - "file": "dialogflow_v2beta1_generated_phone_numbers_update_phone_number_sync.py", + "description": "Sample for SuggestSmartReplies", + "file": "dialogflow_v2beta1_generated_participants_suggest_smart_replies_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_PhoneNumbers_UpdatePhoneNumber_sync", + "regionTag": "dialogflow_v2beta1_generated_Participants_SuggestSmartReplies_sync", "segments": [ { - "end": 50, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 50, + "end": 51, "start": 27, "type": "SHORT" }, @@ -15805,52 +15783,52 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 44, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 47, - "start": 45, + "end": 48, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 51, - "start": 48, + "end": 52, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_phone_numbers_update_phone_number_sync.py" + "title": "dialogflow_v2beta1_generated_participants_suggest_smart_replies_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesAsyncClient", - "shortName": "SessionEntityTypesAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient", + "shortName": "ParticipantsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesAsyncClient.create_session_entity_type", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsAsyncClient.update_participant", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes.CreateSessionEntityType", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.UpdateParticipant", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes", - "shortName": "SessionEntityTypes" + "fullName": "google.cloud.dialogflow.v2beta1.Participants", + "shortName": "Participants" }, - "shortName": "CreateSessionEntityType" + "shortName": "UpdateParticipant" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.CreateSessionEntityTypeRequest" + "type": "google.cloud.dialogflow_v2beta1.types.UpdateParticipantRequest" }, { - "name": "parent", - "type": "str" + "name": "participant", + "type": "google.cloud.dialogflow_v2beta1.types.Participant" }, { - "name": "session_entity_type", - "type": "google.cloud.dialogflow_v2beta1.types.SessionEntityType" + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" }, { "name": "retry", @@ -15865,22 +15843,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.SessionEntityType", - "shortName": "create_session_entity_type" + "resultType": "google.cloud.dialogflow_v2beta1.types.Participant", + "shortName": "update_participant" }, - "description": "Sample for CreateSessionEntityType", - "file": "dialogflow_v2beta1_generated_session_entity_types_create_session_entity_type_async.py", + "description": "Sample for UpdateParticipant", + "file": "dialogflow_v2beta1_generated_participants_update_participant_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_SessionEntityTypes_CreateSessionEntityType_async", + "regionTag": "dialogflow_v2beta1_generated_Participants_UpdateParticipant_async", "segments": [ { - "end": 51, + "end": 50, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 50, "start": 27, "type": "SHORT" }, @@ -15890,51 +15868,51 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 44, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 47, + "start": 45, "type": "REQUEST_EXECUTION" }, { - "end": 52, - "start": 49, + "end": 51, + "start": 48, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_session_entity_types_create_session_entity_type_async.py" + "title": "dialogflow_v2beta1_generated_participants_update_participant_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesClient", - "shortName": "SessionEntityTypesClient" + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient", + "shortName": "ParticipantsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesClient.create_session_entity_type", + "fullName": "google.cloud.dialogflow_v2beta1.ParticipantsClient.update_participant", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes.CreateSessionEntityType", + "fullName": "google.cloud.dialogflow.v2beta1.Participants.UpdateParticipant", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes", - "shortName": "SessionEntityTypes" + "fullName": "google.cloud.dialogflow.v2beta1.Participants", + "shortName": "Participants" }, - "shortName": "CreateSessionEntityType" + "shortName": "UpdateParticipant" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.CreateSessionEntityTypeRequest" + "type": "google.cloud.dialogflow_v2beta1.types.UpdateParticipantRequest" }, { - "name": "parent", - "type": "str" + "name": "participant", + "type": "google.cloud.dialogflow_v2beta1.types.Participant" }, { - "name": "session_entity_type", - "type": "google.cloud.dialogflow_v2beta1.types.SessionEntityType" + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" }, { "name": "retry", @@ -15949,22 +15927,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.SessionEntityType", - "shortName": "create_session_entity_type" + "resultType": "google.cloud.dialogflow_v2beta1.types.Participant", + "shortName": "update_participant" }, - "description": "Sample for CreateSessionEntityType", - "file": "dialogflow_v2beta1_generated_session_entity_types_create_session_entity_type_sync.py", + "description": "Sample for UpdateParticipant", + "file": "dialogflow_v2beta1_generated_participants_update_participant_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_SessionEntityTypes_CreateSessionEntityType_sync", + "regionTag": "dialogflow_v2beta1_generated_Participants_UpdateParticipant_sync", "segments": [ { - "end": 51, + "end": 50, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 50, "start": 27, "type": "SHORT" }, @@ -15974,44 +15952,44 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 45, + "end": 44, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 48, - "start": 46, + "end": 47, + "start": 45, "type": "REQUEST_EXECUTION" }, { - "end": 52, - "start": 49, + "end": 51, + "start": 48, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_session_entity_types_create_session_entity_type_sync.py" + "title": "dialogflow_v2beta1_generated_participants_update_participant_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesAsyncClient", - "shortName": "SessionEntityTypesAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersAsyncClient", + "shortName": "PhoneNumbersAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesAsyncClient.delete_session_entity_type", + "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersAsyncClient.delete_phone_number", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes.DeleteSessionEntityType", + "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers.DeletePhoneNumber", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes", - "shortName": "SessionEntityTypes" + "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers", + "shortName": "PhoneNumbers" }, - "shortName": "DeleteSessionEntityType" + "shortName": "DeletePhoneNumber" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.DeleteSessionEntityTypeRequest" + "type": "google.cloud.dialogflow_v2beta1.types.DeletePhoneNumberRequest" }, { "name": "name", @@ -16030,21 +16008,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "shortName": "delete_session_entity_type" + "resultType": "google.cloud.dialogflow_v2beta1.types.PhoneNumber", + "shortName": "delete_phone_number" }, - "description": "Sample for DeleteSessionEntityType", - "file": "dialogflow_v2beta1_generated_session_entity_types_delete_session_entity_type_async.py", + "description": "Sample for DeletePhoneNumber", + "file": "dialogflow_v2beta1_generated_phone_numbers_delete_phone_number_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_SessionEntityTypes_DeleteSessionEntityType_async", + "regionTag": "dialogflow_v2beta1_generated_PhoneNumbers_DeletePhoneNumber_async", "segments": [ { - "end": 49, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 49, + "end": 51, "start": 27, "type": "SHORT" }, @@ -16059,36 +16038,38 @@ "type": "REQUEST_INITIALIZATION" }, { + "end": 48, "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 50, + "end": 52, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_session_entity_types_delete_session_entity_type_async.py" + "title": "dialogflow_v2beta1_generated_phone_numbers_delete_phone_number_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesClient", - "shortName": "SessionEntityTypesClient" + "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersClient", + "shortName": "PhoneNumbersClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesClient.delete_session_entity_type", + "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersClient.delete_phone_number", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes.DeleteSessionEntityType", + "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers.DeletePhoneNumber", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes", - "shortName": "SessionEntityTypes" + "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers", + "shortName": "PhoneNumbers" }, - "shortName": "DeleteSessionEntityType" + "shortName": "DeletePhoneNumber" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.DeleteSessionEntityTypeRequest" + "type": "google.cloud.dialogflow_v2beta1.types.DeletePhoneNumberRequest" }, { "name": "name", @@ -16107,21 +16088,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "shortName": "delete_session_entity_type" + "resultType": "google.cloud.dialogflow_v2beta1.types.PhoneNumber", + "shortName": "delete_phone_number" }, - "description": "Sample for DeleteSessionEntityType", - "file": "dialogflow_v2beta1_generated_session_entity_types_delete_session_entity_type_sync.py", + "description": "Sample for DeletePhoneNumber", + "file": "dialogflow_v2beta1_generated_phone_numbers_delete_phone_number_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_SessionEntityTypes_DeleteSessionEntityType_sync", + "regionTag": "dialogflow_v2beta1_generated_PhoneNumbers_DeletePhoneNumber_sync", "segments": [ { - "end": 49, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 49, + "end": 51, "start": 27, "type": "SHORT" }, @@ -16136,40 +16118,42 @@ "type": "REQUEST_INITIALIZATION" }, { + "end": 48, "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 50, + "end": 52, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_session_entity_types_delete_session_entity_type_sync.py" + "title": "dialogflow_v2beta1_generated_phone_numbers_delete_phone_number_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesAsyncClient", - "shortName": "SessionEntityTypesAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersAsyncClient", + "shortName": "PhoneNumbersAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesAsyncClient.get_session_entity_type", + "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersAsyncClient.list_phone_numbers", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes.GetSessionEntityType", + "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers.ListPhoneNumbers", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes", - "shortName": "SessionEntityTypes" + "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers", + "shortName": "PhoneNumbers" }, - "shortName": "GetSessionEntityType" + "shortName": "ListPhoneNumbers" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.GetSessionEntityTypeRequest" + "type": "google.cloud.dialogflow_v2beta1.types.ListPhoneNumbersRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -16185,22 +16169,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.SessionEntityType", - "shortName": "get_session_entity_type" + "resultType": "google.cloud.dialogflow_v2beta1.services.phone_numbers.pagers.ListPhoneNumbersAsyncPager", + "shortName": "list_phone_numbers" }, - "description": "Sample for GetSessionEntityType", - "file": "dialogflow_v2beta1_generated_session_entity_types_get_session_entity_type_async.py", + "description": "Sample for ListPhoneNumbers", + "file": "dialogflow_v2beta1_generated_phone_numbers_list_phone_numbers_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_SessionEntityTypes_GetSessionEntityType_async", + "regionTag": "dialogflow_v2beta1_generated_PhoneNumbers_ListPhoneNumbers_async", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -16220,36 +16204,36 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_session_entity_types_get_session_entity_type_async.py" + "title": "dialogflow_v2beta1_generated_phone_numbers_list_phone_numbers_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesClient", - "shortName": "SessionEntityTypesClient" + "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersClient", + "shortName": "PhoneNumbersClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesClient.get_session_entity_type", + "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersClient.list_phone_numbers", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes.GetSessionEntityType", + "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers.ListPhoneNumbers", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes", - "shortName": "SessionEntityTypes" + "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers", + "shortName": "PhoneNumbers" }, - "shortName": "GetSessionEntityType" + "shortName": "ListPhoneNumbers" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.GetSessionEntityTypeRequest" + "type": "google.cloud.dialogflow_v2beta1.types.ListPhoneNumbersRequest" }, { - "name": "name", + "name": "parent", "type": "str" }, { @@ -16265,22 +16249,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.SessionEntityType", - "shortName": "get_session_entity_type" + "resultType": "google.cloud.dialogflow_v2beta1.services.phone_numbers.pagers.ListPhoneNumbersPager", + "shortName": "list_phone_numbers" }, - "description": "Sample for GetSessionEntityType", - "file": "dialogflow_v2beta1_generated_session_entity_types_get_session_entity_type_sync.py", + "description": "Sample for ListPhoneNumbers", + "file": "dialogflow_v2beta1_generated_phone_numbers_list_phone_numbers_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_SessionEntityTypes_GetSessionEntityType_sync", + "regionTag": "dialogflow_v2beta1_generated_PhoneNumbers_ListPhoneNumbers_sync", "segments": [ { - "end": 51, + "end": 52, "start": 27, "type": "FULL" }, { - "end": 51, + "end": 52, "start": 27, "type": "SHORT" }, @@ -16300,37 +16284,37 @@ "type": "REQUEST_EXECUTION" }, { - "end": 52, + "end": 53, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_session_entity_types_get_session_entity_type_sync.py" + "title": "dialogflow_v2beta1_generated_phone_numbers_list_phone_numbers_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesAsyncClient", - "shortName": "SessionEntityTypesAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersAsyncClient", + "shortName": "PhoneNumbersAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesAsyncClient.list_session_entity_types", + "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersAsyncClient.undelete_phone_number", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes.ListSessionEntityTypes", + "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers.UndeletePhoneNumber", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes", - "shortName": "SessionEntityTypes" + "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers", + "shortName": "PhoneNumbers" }, - "shortName": "ListSessionEntityTypes" + "shortName": "UndeletePhoneNumber" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.ListSessionEntityTypesRequest" + "type": "google.cloud.dialogflow_v2beta1.types.UndeletePhoneNumberRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, { @@ -16346,22 +16330,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.services.session_entity_types.pagers.ListSessionEntityTypesAsyncPager", - "shortName": "list_session_entity_types" + "resultType": "google.cloud.dialogflow_v2beta1.types.PhoneNumber", + "shortName": "undelete_phone_number" }, - "description": "Sample for ListSessionEntityTypes", - "file": "dialogflow_v2beta1_generated_session_entity_types_list_session_entity_types_async.py", + "description": "Sample for UndeletePhoneNumber", + "file": "dialogflow_v2beta1_generated_phone_numbers_undelete_phone_number_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_SessionEntityTypes_ListSessionEntityTypes_async", + "regionTag": "dialogflow_v2beta1_generated_PhoneNumbers_UndeletePhoneNumber_async", "segments": [ { - "end": 52, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 51, "start": 27, "type": "SHORT" }, @@ -16381,36 +16365,36 @@ "type": "REQUEST_EXECUTION" }, { - "end": 53, + "end": 52, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_session_entity_types_list_session_entity_types_async.py" + "title": "dialogflow_v2beta1_generated_phone_numbers_undelete_phone_number_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesClient", - "shortName": "SessionEntityTypesClient" + "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersClient", + "shortName": "PhoneNumbersClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesClient.list_session_entity_types", + "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersClient.undelete_phone_number", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes.ListSessionEntityTypes", + "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers.UndeletePhoneNumber", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes", - "shortName": "SessionEntityTypes" + "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers", + "shortName": "PhoneNumbers" }, - "shortName": "ListSessionEntityTypes" + "shortName": "UndeletePhoneNumber" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.ListSessionEntityTypesRequest" + "type": "google.cloud.dialogflow_v2beta1.types.UndeletePhoneNumberRequest" }, { - "name": "parent", + "name": "name", "type": "str" }, { @@ -16426,22 +16410,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.services.session_entity_types.pagers.ListSessionEntityTypesPager", - "shortName": "list_session_entity_types" + "resultType": "google.cloud.dialogflow_v2beta1.types.PhoneNumber", + "shortName": "undelete_phone_number" }, - "description": "Sample for ListSessionEntityTypes", - "file": "dialogflow_v2beta1_generated_session_entity_types_list_session_entity_types_sync.py", + "description": "Sample for UndeletePhoneNumber", + "file": "dialogflow_v2beta1_generated_phone_numbers_undelete_phone_number_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_SessionEntityTypes_ListSessionEntityTypes_sync", + "regionTag": "dialogflow_v2beta1_generated_PhoneNumbers_UndeletePhoneNumber_sync", "segments": [ { - "end": 52, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 52, + "end": 51, "start": 27, "type": "SHORT" }, @@ -16461,38 +16445,38 @@ "type": "REQUEST_EXECUTION" }, { - "end": 53, + "end": 52, "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_session_entity_types_list_session_entity_types_sync.py" + "title": "dialogflow_v2beta1_generated_phone_numbers_undelete_phone_number_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesAsyncClient", - "shortName": "SessionEntityTypesAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersAsyncClient", + "shortName": "PhoneNumbersAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesAsyncClient.update_session_entity_type", + "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersAsyncClient.update_phone_number", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes.UpdateSessionEntityType", + "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers.UpdatePhoneNumber", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes", - "shortName": "SessionEntityTypes" + "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers", + "shortName": "PhoneNumbers" }, - "shortName": "UpdateSessionEntityType" + "shortName": "UpdatePhoneNumber" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.UpdateSessionEntityTypeRequest" + "type": "google.cloud.dialogflow_v2beta1.types.UpdatePhoneNumberRequest" }, { - "name": "session_entity_type", - "type": "google.cloud.dialogflow_v2beta1.types.SessionEntityType" + "name": "phone_number", + "type": "google.cloud.dialogflow_v2beta1.types.PhoneNumber" }, { "name": "update_mask", @@ -16511,14 +16495,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.SessionEntityType", - "shortName": "update_session_entity_type" + "resultType": "google.cloud.dialogflow_v2beta1.types.PhoneNumber", + "shortName": "update_phone_number" }, - "description": "Sample for UpdateSessionEntityType", - "file": "dialogflow_v2beta1_generated_session_entity_types_update_session_entity_type_async.py", + "description": "Sample for UpdatePhoneNumber", + "file": "dialogflow_v2beta1_generated_phone_numbers_update_phone_number_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_SessionEntityTypes_UpdateSessionEntityType_async", + "regionTag": "dialogflow_v2beta1_generated_PhoneNumbers_UpdatePhoneNumber_async", "segments": [ { "end": 50, @@ -16551,32 +16535,32 @@ "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_session_entity_types_update_session_entity_type_async.py" + "title": "dialogflow_v2beta1_generated_phone_numbers_update_phone_number_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesClient", - "shortName": "SessionEntityTypesClient" + "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersClient", + "shortName": "PhoneNumbersClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesClient.update_session_entity_type", + "fullName": "google.cloud.dialogflow_v2beta1.PhoneNumbersClient.update_phone_number", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes.UpdateSessionEntityType", + "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers.UpdatePhoneNumber", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes", - "shortName": "SessionEntityTypes" + "fullName": "google.cloud.dialogflow.v2beta1.PhoneNumbers", + "shortName": "PhoneNumbers" }, - "shortName": "UpdateSessionEntityType" + "shortName": "UpdatePhoneNumber" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.UpdateSessionEntityTypeRequest" + "type": "google.cloud.dialogflow_v2beta1.types.UpdatePhoneNumberRequest" }, { - "name": "session_entity_type", - "type": "google.cloud.dialogflow_v2beta1.types.SessionEntityType" + "name": "phone_number", + "type": "google.cloud.dialogflow_v2beta1.types.PhoneNumber" }, { "name": "update_mask", @@ -16595,14 +16579,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.SessionEntityType", - "shortName": "update_session_entity_type" + "resultType": "google.cloud.dialogflow_v2beta1.types.PhoneNumber", + "shortName": "update_phone_number" }, - "description": "Sample for UpdateSessionEntityType", - "file": "dialogflow_v2beta1_generated_session_entity_types_update_session_entity_type_sync.py", + "description": "Sample for UpdatePhoneNumber", + "file": "dialogflow_v2beta1_generated_phone_numbers_update_phone_number_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_SessionEntityTypes_UpdateSessionEntityType_sync", + "regionTag": "dialogflow_v2beta1_generated_PhoneNumbers_UpdatePhoneNumber_sync", "segments": [ { "end": 50, @@ -16635,37 +16619,37 @@ "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_session_entity_types_update_session_entity_type_sync.py" + "title": "dialogflow_v2beta1_generated_phone_numbers_update_phone_number_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SessionsAsyncClient", - "shortName": "SessionsAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesAsyncClient", + "shortName": "SessionEntityTypesAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SessionsAsyncClient.detect_intent", + "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesAsyncClient.create_session_entity_type", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Sessions.DetectIntent", + "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes.CreateSessionEntityType", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Sessions", - "shortName": "Sessions" + "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes", + "shortName": "SessionEntityTypes" }, - "shortName": "DetectIntent" + "shortName": "CreateSessionEntityType" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.DetectIntentRequest" + "type": "google.cloud.dialogflow_v2beta1.types.CreateSessionEntityTypeRequest" }, { - "name": "session", + "name": "parent", "type": "str" }, { - "name": "query_input", - "type": "google.cloud.dialogflow_v2beta1.types.QueryInput" + "name": "session_entity_type", + "type": "google.cloud.dialogflow_v2beta1.types.SessionEntityType" }, { "name": "retry", @@ -16680,22 +16664,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.DetectIntentResponse", - "shortName": "detect_intent" + "resultType": "google.cloud.dialogflow_v2beta1.types.SessionEntityType", + "shortName": "create_session_entity_type" }, - "description": "Sample for DetectIntent", - "file": "dialogflow_v2beta1_generated_sessions_detect_intent_async.py", + "description": "Sample for CreateSessionEntityType", + "file": "dialogflow_v2beta1_generated_session_entity_types_create_session_entity_type_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Sessions_DetectIntent_async", + "regionTag": "dialogflow_v2beta1_generated_SessionEntityTypes_CreateSessionEntityType_async", "segments": [ { - "end": 57, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 57, + "end": 51, "start": 27, "type": "SHORT" }, @@ -16705,51 +16689,51 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 51, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 54, - "start": 52, + "end": 48, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 58, - "start": 55, + "end": 52, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_sessions_detect_intent_async.py" + "title": "dialogflow_v2beta1_generated_session_entity_types_create_session_entity_type_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SessionsClient", - "shortName": "SessionsClient" + "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesClient", + "shortName": "SessionEntityTypesClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SessionsClient.detect_intent", + "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesClient.create_session_entity_type", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Sessions.DetectIntent", + "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes.CreateSessionEntityType", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Sessions", - "shortName": "Sessions" + "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes", + "shortName": "SessionEntityTypes" }, - "shortName": "DetectIntent" + "shortName": "CreateSessionEntityType" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.DetectIntentRequest" + "type": "google.cloud.dialogflow_v2beta1.types.CreateSessionEntityTypeRequest" }, { - "name": "session", + "name": "parent", "type": "str" }, { - "name": "query_input", - "type": "google.cloud.dialogflow_v2beta1.types.QueryInput" + "name": "session_entity_type", + "type": "google.cloud.dialogflow_v2beta1.types.SessionEntityType" }, { "name": "retry", @@ -16764,22 +16748,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.DetectIntentResponse", - "shortName": "detect_intent" + "resultType": "google.cloud.dialogflow_v2beta1.types.SessionEntityType", + "shortName": "create_session_entity_type" }, - "description": "Sample for DetectIntent", - "file": "dialogflow_v2beta1_generated_sessions_detect_intent_sync.py", + "description": "Sample for CreateSessionEntityType", + "file": "dialogflow_v2beta1_generated_session_entity_types_create_session_entity_type_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Sessions_DetectIntent_sync", + "regionTag": "dialogflow_v2beta1_generated_SessionEntityTypes_CreateSessionEntityType_sync", "segments": [ { - "end": 57, + "end": 51, "start": 27, "type": "FULL" }, { - "end": 57, + "end": 51, "start": 27, "type": "SHORT" }, @@ -16789,44 +16773,48 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 51, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 54, - "start": 52, + "end": 48, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 58, - "start": 55, + "end": 52, + "start": 49, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_sessions_detect_intent_sync.py" + "title": "dialogflow_v2beta1_generated_session_entity_types_create_session_entity_type_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SessionsAsyncClient", - "shortName": "SessionsAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesAsyncClient", + "shortName": "SessionEntityTypesAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SessionsAsyncClient.streaming_detect_intent", + "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesAsyncClient.delete_session_entity_type", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Sessions.StreamingDetectIntent", + "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes.DeleteSessionEntityType", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Sessions", - "shortName": "Sessions" + "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes", + "shortName": "SessionEntityTypes" }, - "shortName": "StreamingDetectIntent" + "shortName": "DeleteSessionEntityType" }, "parameters": [ { - "name": "requests", - "type": "Iterator[google.cloud.dialogflow_v2beta1.types.StreamingDetectIntentRequest]" + "name": "request", + "type": "google.cloud.dialogflow_v2beta1.types.DeleteSessionEntityTypeRequest" + }, + { + "name": "name", + "type": "str" }, { "name": "retry", @@ -16841,22 +16829,21 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "Iterable[google.cloud.dialogflow_v2beta1.types.StreamingDetectIntentResponse]", - "shortName": "streaming_detect_intent" + "shortName": "delete_session_entity_type" }, - "description": "Sample for StreamingDetectIntent", - "file": "dialogflow_v2beta1_generated_sessions_streaming_detect_intent_async.py", + "description": "Sample for DeleteSessionEntityType", + "file": "dialogflow_v2beta1_generated_session_entity_types_delete_session_entity_type_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Sessions_StreamingDetectIntent_async", + "regionTag": "dialogflow_v2beta1_generated_SessionEntityTypes_DeleteSessionEntityType_async", "segments": [ { - "end": 68, + "end": 49, "start": 27, "type": "FULL" }, { - "end": 68, + "end": 49, "start": 27, "type": "SHORT" }, @@ -16866,43 +16853,1670 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 61, + "end": 45, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 64, - "start": 62, + "start": 46, "type": "REQUEST_EXECUTION" }, { - "end": 69, - "start": 65, + "end": 50, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_sessions_streaming_detect_intent_async.py" + "title": "dialogflow_v2beta1_generated_session_entity_types_delete_session_entity_type_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SessionsClient", - "shortName": "SessionsClient" + "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesClient", + "shortName": "SessionEntityTypesClient" + }, + "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesClient.delete_session_entity_type", + "method": { + "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes.DeleteSessionEntityType", + "service": { + "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes", + "shortName": "SessionEntityTypes" + }, + "shortName": "DeleteSessionEntityType" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflow_v2beta1.types.DeleteSessionEntityTypeRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "shortName": "delete_session_entity_type" + }, + "description": "Sample for DeleteSessionEntityType", + "file": "dialogflow_v2beta1_generated_session_entity_types_delete_session_entity_type_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v2beta1_generated_SessionEntityTypes_DeleteSessionEntityType_sync", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v2beta1_generated_session_entity_types_delete_session_entity_type_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesAsyncClient", + "shortName": "SessionEntityTypesAsyncClient" + }, + "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesAsyncClient.get_session_entity_type", + "method": { + "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes.GetSessionEntityType", + "service": { + "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes", + "shortName": "SessionEntityTypes" + }, + "shortName": "GetSessionEntityType" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflow_v2beta1.types.GetSessionEntityTypeRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.dialogflow_v2beta1.types.SessionEntityType", + "shortName": "get_session_entity_type" + }, + "description": "Sample for GetSessionEntityType", + "file": "dialogflow_v2beta1_generated_session_entity_types_get_session_entity_type_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v2beta1_generated_SessionEntityTypes_GetSessionEntityType_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v2beta1_generated_session_entity_types_get_session_entity_type_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesClient", + "shortName": "SessionEntityTypesClient" + }, + "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesClient.get_session_entity_type", + "method": { + "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes.GetSessionEntityType", + "service": { + "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes", + "shortName": "SessionEntityTypes" + }, + "shortName": "GetSessionEntityType" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflow_v2beta1.types.GetSessionEntityTypeRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.dialogflow_v2beta1.types.SessionEntityType", + "shortName": "get_session_entity_type" + }, + "description": "Sample for GetSessionEntityType", + "file": "dialogflow_v2beta1_generated_session_entity_types_get_session_entity_type_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v2beta1_generated_SessionEntityTypes_GetSessionEntityType_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v2beta1_generated_session_entity_types_get_session_entity_type_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesAsyncClient", + "shortName": "SessionEntityTypesAsyncClient" + }, + "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesAsyncClient.list_session_entity_types", + "method": { + "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes.ListSessionEntityTypes", + "service": { + "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes", + "shortName": "SessionEntityTypes" + }, + "shortName": "ListSessionEntityTypes" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflow_v2beta1.types.ListSessionEntityTypesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.dialogflow_v2beta1.services.session_entity_types.pagers.ListSessionEntityTypesAsyncPager", + "shortName": "list_session_entity_types" + }, + "description": "Sample for ListSessionEntityTypes", + "file": "dialogflow_v2beta1_generated_session_entity_types_list_session_entity_types_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v2beta1_generated_SessionEntityTypes_ListSessionEntityTypes_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v2beta1_generated_session_entity_types_list_session_entity_types_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesClient", + "shortName": "SessionEntityTypesClient" + }, + "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesClient.list_session_entity_types", + "method": { + "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes.ListSessionEntityTypes", + "service": { + "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes", + "shortName": "SessionEntityTypes" + }, + "shortName": "ListSessionEntityTypes" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflow_v2beta1.types.ListSessionEntityTypesRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.dialogflow_v2beta1.services.session_entity_types.pagers.ListSessionEntityTypesPager", + "shortName": "list_session_entity_types" + }, + "description": "Sample for ListSessionEntityTypes", + "file": "dialogflow_v2beta1_generated_session_entity_types_list_session_entity_types_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v2beta1_generated_SessionEntityTypes_ListSessionEntityTypes_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v2beta1_generated_session_entity_types_list_session_entity_types_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesAsyncClient", + "shortName": "SessionEntityTypesAsyncClient" + }, + "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesAsyncClient.update_session_entity_type", + "method": { + "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes.UpdateSessionEntityType", + "service": { + "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes", + "shortName": "SessionEntityTypes" + }, + "shortName": "UpdateSessionEntityType" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflow_v2beta1.types.UpdateSessionEntityTypeRequest" + }, + { + "name": "session_entity_type", + "type": "google.cloud.dialogflow_v2beta1.types.SessionEntityType" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.dialogflow_v2beta1.types.SessionEntityType", + "shortName": "update_session_entity_type" + }, + "description": "Sample for UpdateSessionEntityType", + "file": "dialogflow_v2beta1_generated_session_entity_types_update_session_entity_type_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v2beta1_generated_SessionEntityTypes_UpdateSessionEntityType_async", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v2beta1_generated_session_entity_types_update_session_entity_type_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesClient", + "shortName": "SessionEntityTypesClient" + }, + "fullName": "google.cloud.dialogflow_v2beta1.SessionEntityTypesClient.update_session_entity_type", + "method": { + "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes.UpdateSessionEntityType", + "service": { + "fullName": "google.cloud.dialogflow.v2beta1.SessionEntityTypes", + "shortName": "SessionEntityTypes" + }, + "shortName": "UpdateSessionEntityType" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflow_v2beta1.types.UpdateSessionEntityTypeRequest" + }, + { + "name": "session_entity_type", + "type": "google.cloud.dialogflow_v2beta1.types.SessionEntityType" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.dialogflow_v2beta1.types.SessionEntityType", + "shortName": "update_session_entity_type" + }, + "description": "Sample for UpdateSessionEntityType", + "file": "dialogflow_v2beta1_generated_session_entity_types_update_session_entity_type_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v2beta1_generated_SessionEntityTypes_UpdateSessionEntityType_sync", + "segments": [ + { + "end": 50, + "start": 27, + "type": "FULL" + }, + { + "end": 50, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 47, + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 51, + "start": 48, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v2beta1_generated_session_entity_types_update_session_entity_type_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.dialogflow_v2beta1.SessionsAsyncClient", + "shortName": "SessionsAsyncClient" + }, + "fullName": "google.cloud.dialogflow_v2beta1.SessionsAsyncClient.detect_intent", + "method": { + "fullName": "google.cloud.dialogflow.v2beta1.Sessions.DetectIntent", + "service": { + "fullName": "google.cloud.dialogflow.v2beta1.Sessions", + "shortName": "Sessions" + }, + "shortName": "DetectIntent" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflow_v2beta1.types.DetectIntentRequest" + }, + { + "name": "session", + "type": "str" + }, + { + "name": "query_input", + "type": "google.cloud.dialogflow_v2beta1.types.QueryInput" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.dialogflow_v2beta1.types.DetectIntentResponse", + "shortName": "detect_intent" + }, + "description": "Sample for DetectIntent", + "file": "dialogflow_v2beta1_generated_sessions_detect_intent_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v2beta1_generated_Sessions_DetectIntent_async", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 51, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 52, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v2beta1_generated_sessions_detect_intent_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.dialogflow_v2beta1.SessionsClient", + "shortName": "SessionsClient" + }, + "fullName": "google.cloud.dialogflow_v2beta1.SessionsClient.detect_intent", + "method": { + "fullName": "google.cloud.dialogflow.v2beta1.Sessions.DetectIntent", + "service": { + "fullName": "google.cloud.dialogflow.v2beta1.Sessions", + "shortName": "Sessions" + }, + "shortName": "DetectIntent" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflow_v2beta1.types.DetectIntentRequest" + }, + { + "name": "session", + "type": "str" + }, + { + "name": "query_input", + "type": "google.cloud.dialogflow_v2beta1.types.QueryInput" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.dialogflow_v2beta1.types.DetectIntentResponse", + "shortName": "detect_intent" + }, + "description": "Sample for DetectIntent", + "file": "dialogflow_v2beta1_generated_sessions_detect_intent_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v2beta1_generated_Sessions_DetectIntent_sync", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 51, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 52, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v2beta1_generated_sessions_detect_intent_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.dialogflow_v2beta1.SessionsAsyncClient", + "shortName": "SessionsAsyncClient" + }, + "fullName": "google.cloud.dialogflow_v2beta1.SessionsAsyncClient.streaming_detect_intent", + "method": { + "fullName": "google.cloud.dialogflow.v2beta1.Sessions.StreamingDetectIntent", + "service": { + "fullName": "google.cloud.dialogflow.v2beta1.Sessions", + "shortName": "Sessions" + }, + "shortName": "StreamingDetectIntent" + }, + "parameters": [ + { + "name": "requests", + "type": "Iterator[google.cloud.dialogflow_v2beta1.types.StreamingDetectIntentRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "Iterable[google.cloud.dialogflow_v2beta1.types.StreamingDetectIntentResponse]", + "shortName": "streaming_detect_intent" + }, + "description": "Sample for StreamingDetectIntent", + "file": "dialogflow_v2beta1_generated_sessions_streaming_detect_intent_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v2beta1_generated_Sessions_StreamingDetectIntent_async", + "segments": [ + { + "end": 68, + "start": 27, + "type": "FULL" + }, + { + "end": 68, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 61, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 64, + "start": 62, + "type": "REQUEST_EXECUTION" + }, + { + "end": 69, + "start": 65, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v2beta1_generated_sessions_streaming_detect_intent_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.dialogflow_v2beta1.SessionsClient", + "shortName": "SessionsClient" + }, + "fullName": "google.cloud.dialogflow_v2beta1.SessionsClient.streaming_detect_intent", + "method": { + "fullName": "google.cloud.dialogflow.v2beta1.Sessions.StreamingDetectIntent", + "service": { + "fullName": "google.cloud.dialogflow.v2beta1.Sessions", + "shortName": "Sessions" + }, + "shortName": "StreamingDetectIntent" + }, + "parameters": [ + { + "name": "requests", + "type": "Iterator[google.cloud.dialogflow_v2beta1.types.StreamingDetectIntentRequest]" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "Iterable[google.cloud.dialogflow_v2beta1.types.StreamingDetectIntentResponse]", + "shortName": "streaming_detect_intent" + }, + "description": "Sample for StreamingDetectIntent", + "file": "dialogflow_v2beta1_generated_sessions_streaming_detect_intent_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v2beta1_generated_Sessions_StreamingDetectIntent_sync", + "segments": [ + { + "end": 68, + "start": 27, + "type": "FULL" + }, + { + "end": 68, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 61, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 64, + "start": 62, + "type": "REQUEST_EXECUTION" + }, + { + "end": 69, + "start": 65, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v2beta1_generated_sessions_streaming_detect_intent_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksAsyncClient", + "shortName": "SipTrunksAsyncClient" + }, + "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksAsyncClient.create_sip_trunk", + "method": { + "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks.CreateSipTrunk", + "service": { + "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks", + "shortName": "SipTrunks" + }, + "shortName": "CreateSipTrunk" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflow_v2beta1.types.CreateSipTrunkRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "sip_trunk", + "type": "google.cloud.dialogflow_v2beta1.types.SipTrunk" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.dialogflow_v2beta1.types.SipTrunk", + "shortName": "create_sip_trunk" + }, + "description": "Sample for CreateSipTrunk", + "file": "dialogflow_v2beta1_generated_sip_trunks_create_sip_trunk_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v2beta1_generated_SipTrunks_CreateSipTrunk_async", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v2beta1_generated_sip_trunks_create_sip_trunk_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksClient", + "shortName": "SipTrunksClient" + }, + "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksClient.create_sip_trunk", + "method": { + "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks.CreateSipTrunk", + "service": { + "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks", + "shortName": "SipTrunks" + }, + "shortName": "CreateSipTrunk" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflow_v2beta1.types.CreateSipTrunkRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "sip_trunk", + "type": "google.cloud.dialogflow_v2beta1.types.SipTrunk" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.dialogflow_v2beta1.types.SipTrunk", + "shortName": "create_sip_trunk" + }, + "description": "Sample for CreateSipTrunk", + "file": "dialogflow_v2beta1_generated_sip_trunks_create_sip_trunk_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v2beta1_generated_SipTrunks_CreateSipTrunk_sync", + "segments": [ + { + "end": 55, + "start": 27, + "type": "FULL" + }, + { + "end": 55, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 52, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 56, + "start": 53, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v2beta1_generated_sip_trunks_create_sip_trunk_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksAsyncClient", + "shortName": "SipTrunksAsyncClient" + }, + "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksAsyncClient.delete_sip_trunk", + "method": { + "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks.DeleteSipTrunk", + "service": { + "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks", + "shortName": "SipTrunks" + }, + "shortName": "DeleteSipTrunk" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflow_v2beta1.types.DeleteSipTrunkRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "shortName": "delete_sip_trunk" + }, + "description": "Sample for DeleteSipTrunk", + "file": "dialogflow_v2beta1_generated_sip_trunks_delete_sip_trunk_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v2beta1_generated_SipTrunks_DeleteSipTrunk_async", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v2beta1_generated_sip_trunks_delete_sip_trunk_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksClient", + "shortName": "SipTrunksClient" + }, + "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksClient.delete_sip_trunk", + "method": { + "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks.DeleteSipTrunk", + "service": { + "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks", + "shortName": "SipTrunks" + }, + "shortName": "DeleteSipTrunk" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflow_v2beta1.types.DeleteSipTrunkRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "shortName": "delete_sip_trunk" + }, + "description": "Sample for DeleteSipTrunk", + "file": "dialogflow_v2beta1_generated_sip_trunks_delete_sip_trunk_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v2beta1_generated_SipTrunks_DeleteSipTrunk_sync", + "segments": [ + { + "end": 49, + "start": 27, + "type": "FULL" + }, + { + "end": 49, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v2beta1_generated_sip_trunks_delete_sip_trunk_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksAsyncClient", + "shortName": "SipTrunksAsyncClient" + }, + "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksAsyncClient.get_sip_trunk", + "method": { + "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks.GetSipTrunk", + "service": { + "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks", + "shortName": "SipTrunks" + }, + "shortName": "GetSipTrunk" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflow_v2beta1.types.GetSipTrunkRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.dialogflow_v2beta1.types.SipTrunk", + "shortName": "get_sip_trunk" + }, + "description": "Sample for GetSipTrunk", + "file": "dialogflow_v2beta1_generated_sip_trunks_get_sip_trunk_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v2beta1_generated_SipTrunks_GetSipTrunk_async", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v2beta1_generated_sip_trunks_get_sip_trunk_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksClient", + "shortName": "SipTrunksClient" + }, + "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksClient.get_sip_trunk", + "method": { + "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks.GetSipTrunk", + "service": { + "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks", + "shortName": "SipTrunks" + }, + "shortName": "GetSipTrunk" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflow_v2beta1.types.GetSipTrunkRequest" + }, + { + "name": "name", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.dialogflow_v2beta1.types.SipTrunk", + "shortName": "get_sip_trunk" + }, + "description": "Sample for GetSipTrunk", + "file": "dialogflow_v2beta1_generated_sip_trunks_get_sip_trunk_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v2beta1_generated_SipTrunks_GetSipTrunk_sync", + "segments": [ + { + "end": 51, + "start": 27, + "type": "FULL" + }, + { + "end": 51, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 52, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v2beta1_generated_sip_trunks_get_sip_trunk_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksAsyncClient", + "shortName": "SipTrunksAsyncClient" + }, + "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksAsyncClient.list_sip_trunks", + "method": { + "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks.ListSipTrunks", + "service": { + "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks", + "shortName": "SipTrunks" + }, + "shortName": "ListSipTrunks" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflow_v2beta1.types.ListSipTrunksRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.dialogflow_v2beta1.services.sip_trunks.pagers.ListSipTrunksAsyncPager", + "shortName": "list_sip_trunks" + }, + "description": "Sample for ListSipTrunks", + "file": "dialogflow_v2beta1_generated_sip_trunks_list_sip_trunks_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v2beta1_generated_SipTrunks_ListSipTrunks_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v2beta1_generated_sip_trunks_list_sip_trunks_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksClient", + "shortName": "SipTrunksClient" + }, + "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksClient.list_sip_trunks", + "method": { + "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks.ListSipTrunks", + "service": { + "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks", + "shortName": "SipTrunks" + }, + "shortName": "ListSipTrunks" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflow_v2beta1.types.ListSipTrunksRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.dialogflow_v2beta1.services.sip_trunks.pagers.ListSipTrunksPager", + "shortName": "list_sip_trunks" + }, + "description": "Sample for ListSipTrunks", + "file": "dialogflow_v2beta1_generated_sip_trunks_list_sip_trunks_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v2beta1_generated_SipTrunks_ListSipTrunks_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 45, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 48, + "start": 46, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v2beta1_generated_sip_trunks_list_sip_trunks_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksAsyncClient", + "shortName": "SipTrunksAsyncClient" + }, + "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksAsyncClient.update_sip_trunk", + "method": { + "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks.UpdateSipTrunk", + "service": { + "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks", + "shortName": "SipTrunks" + }, + "shortName": "UpdateSipTrunk" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflow_v2beta1.types.UpdateSipTrunkRequest" + }, + { + "name": "sip_trunk", + "type": "google.cloud.dialogflow_v2beta1.types.SipTrunk" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, Union[str, bytes]]]" + } + ], + "resultType": "google.cloud.dialogflow_v2beta1.types.SipTrunk", + "shortName": "update_sip_trunk" + }, + "description": "Sample for UpdateSipTrunk", + "file": "dialogflow_v2beta1_generated_sip_trunks_update_sip_trunk_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v2beta1_generated_SipTrunks_UpdateSipTrunk_async", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v2beta1_generated_sip_trunks_update_sip_trunk_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksClient", + "shortName": "SipTrunksClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SessionsClient.streaming_detect_intent", + "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksClient.update_sip_trunk", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.Sessions.StreamingDetectIntent", + "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks.UpdateSipTrunk", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.Sessions", - "shortName": "Sessions" + "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks", + "shortName": "SipTrunks" }, - "shortName": "StreamingDetectIntent" + "shortName": "UpdateSipTrunk" }, "parameters": [ { - "name": "requests", - "type": "Iterator[google.cloud.dialogflow_v2beta1.types.StreamingDetectIntentRequest]" + "name": "request", + "type": "google.cloud.dialogflow_v2beta1.types.UpdateSipTrunkRequest" + }, + { + "name": "sip_trunk", + "type": "google.cloud.dialogflow_v2beta1.types.SipTrunk" + }, + { + "name": "update_mask", + "type": "google.protobuf.field_mask_pb2.FieldMask" }, { "name": "retry", @@ -16917,22 +18531,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "Iterable[google.cloud.dialogflow_v2beta1.types.StreamingDetectIntentResponse]", - "shortName": "streaming_detect_intent" + "resultType": "google.cloud.dialogflow_v2beta1.types.SipTrunk", + "shortName": "update_sip_trunk" }, - "description": "Sample for StreamingDetectIntent", - "file": "dialogflow_v2beta1_generated_sessions_streaming_detect_intent_sync.py", + "description": "Sample for UpdateSipTrunk", + "file": "dialogflow_v2beta1_generated_sip_trunks_update_sip_trunk_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_Sessions_StreamingDetectIntent_sync", + "regionTag": "dialogflow_v2beta1_generated_SipTrunks_UpdateSipTrunk_sync", "segments": [ { - "end": 68, + "end": 54, "start": 27, "type": "FULL" }, { - "end": 68, + "end": 54, "start": 27, "type": "SHORT" }, @@ -16942,52 +18556,56 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 61, + "end": 48, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 64, - "start": 62, + "end": 51, + "start": 49, "type": "REQUEST_EXECUTION" }, { - "end": 69, - "start": 65, + "end": 55, + "start": 52, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_sessions_streaming_detect_intent_sync.py" + "title": "dialogflow_v2beta1_generated_sip_trunks_update_sip_trunk_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksAsyncClient", - "shortName": "SipTrunksAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.ToolsAsyncClient", + "shortName": "ToolsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksAsyncClient.create_sip_trunk", + "fullName": "google.cloud.dialogflow_v2beta1.ToolsAsyncClient.create_tool", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks.CreateSipTrunk", + "fullName": "google.cloud.dialogflow.v2beta1.Tools.CreateTool", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks", - "shortName": "SipTrunks" + "fullName": "google.cloud.dialogflow.v2beta1.Tools", + "shortName": "Tools" }, - "shortName": "CreateSipTrunk" + "shortName": "CreateTool" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.CreateSipTrunkRequest" + "type": "google.cloud.dialogflow_v2beta1.types.CreateToolRequest" }, { "name": "parent", "type": "str" }, { - "name": "sip_trunk", - "type": "google.cloud.dialogflow_v2beta1.types.SipTrunk" + "name": "tool", + "type": "google.cloud.dialogflow_v2beta1.types.Tool" + }, + { + "name": "tool_id", + "type": "str" }, { "name": "retry", @@ -17002,22 +18620,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.SipTrunk", - "shortName": "create_sip_trunk" + "resultType": "google.cloud.dialogflow_v2beta1.types.Tool", + "shortName": "create_tool" }, - "description": "Sample for CreateSipTrunk", - "file": "dialogflow_v2beta1_generated_sip_trunks_create_sip_trunk_async.py", + "description": "Sample for CreateTool", + "file": "dialogflow_v2beta1_generated_tools_create_tool_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_SipTrunks_CreateSipTrunk_async", + "regionTag": "dialogflow_v2beta1_generated_Tools_CreateTool_async", "segments": [ { - "end": 55, + "end": 56, "start": 27, "type": "FULL" }, { - "end": 55, + "end": 56, "start": 27, "type": "SHORT" }, @@ -17027,51 +18645,55 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 49, + "end": 50, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 52, - "start": 50, + "end": 53, + "start": 51, "type": "REQUEST_EXECUTION" }, { - "end": 56, - "start": 53, + "end": 57, + "start": 54, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_sip_trunks_create_sip_trunk_async.py" + "title": "dialogflow_v2beta1_generated_tools_create_tool_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksClient", - "shortName": "SipTrunksClient" + "fullName": "google.cloud.dialogflow_v2beta1.ToolsClient", + "shortName": "ToolsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksClient.create_sip_trunk", + "fullName": "google.cloud.dialogflow_v2beta1.ToolsClient.create_tool", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks.CreateSipTrunk", + "fullName": "google.cloud.dialogflow.v2beta1.Tools.CreateTool", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks", - "shortName": "SipTrunks" + "fullName": "google.cloud.dialogflow.v2beta1.Tools", + "shortName": "Tools" }, - "shortName": "CreateSipTrunk" + "shortName": "CreateTool" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.CreateSipTrunkRequest" + "type": "google.cloud.dialogflow_v2beta1.types.CreateToolRequest" }, { "name": "parent", "type": "str" }, { - "name": "sip_trunk", - "type": "google.cloud.dialogflow_v2beta1.types.SipTrunk" + "name": "tool", + "type": "google.cloud.dialogflow_v2beta1.types.Tool" + }, + { + "name": "tool_id", + "type": "str" }, { "name": "retry", @@ -17086,22 +18708,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.SipTrunk", - "shortName": "create_sip_trunk" + "resultType": "google.cloud.dialogflow_v2beta1.types.Tool", + "shortName": "create_tool" }, - "description": "Sample for CreateSipTrunk", - "file": "dialogflow_v2beta1_generated_sip_trunks_create_sip_trunk_sync.py", + "description": "Sample for CreateTool", + "file": "dialogflow_v2beta1_generated_tools_create_tool_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_SipTrunks_CreateSipTrunk_sync", + "regionTag": "dialogflow_v2beta1_generated_Tools_CreateTool_sync", "segments": [ { - "end": 55, + "end": 56, "start": 27, "type": "FULL" }, { - "end": 55, + "end": 56, "start": 27, "type": "SHORT" }, @@ -17111,44 +18733,44 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 49, + "end": 50, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 52, - "start": 50, + "end": 53, + "start": 51, "type": "REQUEST_EXECUTION" }, { - "end": 56, - "start": 53, + "end": 57, + "start": 54, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_sip_trunks_create_sip_trunk_sync.py" + "title": "dialogflow_v2beta1_generated_tools_create_tool_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksAsyncClient", - "shortName": "SipTrunksAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.ToolsAsyncClient", + "shortName": "ToolsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksAsyncClient.delete_sip_trunk", + "fullName": "google.cloud.dialogflow_v2beta1.ToolsAsyncClient.delete_tool", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks.DeleteSipTrunk", + "fullName": "google.cloud.dialogflow.v2beta1.Tools.DeleteTool", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks", - "shortName": "SipTrunks" + "fullName": "google.cloud.dialogflow.v2beta1.Tools", + "shortName": "Tools" }, - "shortName": "DeleteSipTrunk" + "shortName": "DeleteTool" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.DeleteSipTrunkRequest" + "type": "google.cloud.dialogflow_v2beta1.types.DeleteToolRequest" }, { "name": "name", @@ -17167,13 +18789,13 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "shortName": "delete_sip_trunk" + "shortName": "delete_tool" }, - "description": "Sample for DeleteSipTrunk", - "file": "dialogflow_v2beta1_generated_sip_trunks_delete_sip_trunk_async.py", + "description": "Sample for DeleteTool", + "file": "dialogflow_v2beta1_generated_tools_delete_tool_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_SipTrunks_DeleteSipTrunk_async", + "regionTag": "dialogflow_v2beta1_generated_Tools_DeleteTool_async", "segments": [ { "end": 49, @@ -17204,28 +18826,28 @@ "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_sip_trunks_delete_sip_trunk_async.py" + "title": "dialogflow_v2beta1_generated_tools_delete_tool_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksClient", - "shortName": "SipTrunksClient" + "fullName": "google.cloud.dialogflow_v2beta1.ToolsClient", + "shortName": "ToolsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksClient.delete_sip_trunk", + "fullName": "google.cloud.dialogflow_v2beta1.ToolsClient.delete_tool", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks.DeleteSipTrunk", + "fullName": "google.cloud.dialogflow.v2beta1.Tools.DeleteTool", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks", - "shortName": "SipTrunks" + "fullName": "google.cloud.dialogflow.v2beta1.Tools", + "shortName": "Tools" }, - "shortName": "DeleteSipTrunk" + "shortName": "DeleteTool" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.DeleteSipTrunkRequest" + "type": "google.cloud.dialogflow_v2beta1.types.DeleteToolRequest" }, { "name": "name", @@ -17244,13 +18866,13 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "shortName": "delete_sip_trunk" + "shortName": "delete_tool" }, - "description": "Sample for DeleteSipTrunk", - "file": "dialogflow_v2beta1_generated_sip_trunks_delete_sip_trunk_sync.py", + "description": "Sample for DeleteTool", + "file": "dialogflow_v2beta1_generated_tools_delete_tool_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_SipTrunks_DeleteSipTrunk_sync", + "regionTag": "dialogflow_v2beta1_generated_Tools_DeleteTool_sync", "segments": [ { "end": 49, @@ -17281,29 +18903,29 @@ "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_sip_trunks_delete_sip_trunk_sync.py" + "title": "dialogflow_v2beta1_generated_tools_delete_tool_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksAsyncClient", - "shortName": "SipTrunksAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.ToolsAsyncClient", + "shortName": "ToolsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksAsyncClient.get_sip_trunk", + "fullName": "google.cloud.dialogflow_v2beta1.ToolsAsyncClient.get_tool", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks.GetSipTrunk", + "fullName": "google.cloud.dialogflow.v2beta1.Tools.GetTool", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks", - "shortName": "SipTrunks" + "fullName": "google.cloud.dialogflow.v2beta1.Tools", + "shortName": "Tools" }, - "shortName": "GetSipTrunk" + "shortName": "GetTool" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.GetSipTrunkRequest" + "type": "google.cloud.dialogflow_v2beta1.types.GetToolRequest" }, { "name": "name", @@ -17322,14 +18944,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.SipTrunk", - "shortName": "get_sip_trunk" + "resultType": "google.cloud.dialogflow_v2beta1.types.Tool", + "shortName": "get_tool" }, - "description": "Sample for GetSipTrunk", - "file": "dialogflow_v2beta1_generated_sip_trunks_get_sip_trunk_async.py", + "description": "Sample for GetTool", + "file": "dialogflow_v2beta1_generated_tools_get_tool_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_SipTrunks_GetSipTrunk_async", + "regionTag": "dialogflow_v2beta1_generated_Tools_GetTool_async", "segments": [ { "end": 51, @@ -17362,28 +18984,28 @@ "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_sip_trunks_get_sip_trunk_async.py" + "title": "dialogflow_v2beta1_generated_tools_get_tool_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksClient", - "shortName": "SipTrunksClient" + "fullName": "google.cloud.dialogflow_v2beta1.ToolsClient", + "shortName": "ToolsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksClient.get_sip_trunk", + "fullName": "google.cloud.dialogflow_v2beta1.ToolsClient.get_tool", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks.GetSipTrunk", + "fullName": "google.cloud.dialogflow.v2beta1.Tools.GetTool", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks", - "shortName": "SipTrunks" + "fullName": "google.cloud.dialogflow.v2beta1.Tools", + "shortName": "Tools" }, - "shortName": "GetSipTrunk" + "shortName": "GetTool" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.GetSipTrunkRequest" + "type": "google.cloud.dialogflow_v2beta1.types.GetToolRequest" }, { "name": "name", @@ -17402,14 +19024,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.SipTrunk", - "shortName": "get_sip_trunk" + "resultType": "google.cloud.dialogflow_v2beta1.types.Tool", + "shortName": "get_tool" }, - "description": "Sample for GetSipTrunk", - "file": "dialogflow_v2beta1_generated_sip_trunks_get_sip_trunk_sync.py", + "description": "Sample for GetTool", + "file": "dialogflow_v2beta1_generated_tools_get_tool_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_SipTrunks_GetSipTrunk_sync", + "regionTag": "dialogflow_v2beta1_generated_Tools_GetTool_sync", "segments": [ { "end": 51, @@ -17442,29 +19064,29 @@ "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_sip_trunks_get_sip_trunk_sync.py" + "title": "dialogflow_v2beta1_generated_tools_get_tool_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksAsyncClient", - "shortName": "SipTrunksAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.ToolsAsyncClient", + "shortName": "ToolsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksAsyncClient.list_sip_trunks", + "fullName": "google.cloud.dialogflow_v2beta1.ToolsAsyncClient.list_tools", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks.ListSipTrunks", + "fullName": "google.cloud.dialogflow.v2beta1.Tools.ListTools", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks", - "shortName": "SipTrunks" + "fullName": "google.cloud.dialogflow.v2beta1.Tools", + "shortName": "Tools" }, - "shortName": "ListSipTrunks" + "shortName": "ListTools" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.ListSipTrunksRequest" + "type": "google.cloud.dialogflow_v2beta1.types.ListToolsRequest" }, { "name": "parent", @@ -17483,14 +19105,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.services.sip_trunks.pagers.ListSipTrunksAsyncPager", - "shortName": "list_sip_trunks" + "resultType": "google.cloud.dialogflow_v2beta1.services.tools.pagers.ListToolsAsyncPager", + "shortName": "list_tools" }, - "description": "Sample for ListSipTrunks", - "file": "dialogflow_v2beta1_generated_sip_trunks_list_sip_trunks_async.py", + "description": "Sample for ListTools", + "file": "dialogflow_v2beta1_generated_tools_list_tools_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_SipTrunks_ListSipTrunks_async", + "regionTag": "dialogflow_v2beta1_generated_Tools_ListTools_async", "segments": [ { "end": 52, @@ -17523,28 +19145,28 @@ "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_sip_trunks_list_sip_trunks_async.py" + "title": "dialogflow_v2beta1_generated_tools_list_tools_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksClient", - "shortName": "SipTrunksClient" + "fullName": "google.cloud.dialogflow_v2beta1.ToolsClient", + "shortName": "ToolsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksClient.list_sip_trunks", + "fullName": "google.cloud.dialogflow_v2beta1.ToolsClient.list_tools", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks.ListSipTrunks", + "fullName": "google.cloud.dialogflow.v2beta1.Tools.ListTools", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks", - "shortName": "SipTrunks" + "fullName": "google.cloud.dialogflow.v2beta1.Tools", + "shortName": "Tools" }, - "shortName": "ListSipTrunks" + "shortName": "ListTools" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.ListSipTrunksRequest" + "type": "google.cloud.dialogflow_v2beta1.types.ListToolsRequest" }, { "name": "parent", @@ -17563,14 +19185,14 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.services.sip_trunks.pagers.ListSipTrunksPager", - "shortName": "list_sip_trunks" + "resultType": "google.cloud.dialogflow_v2beta1.services.tools.pagers.ListToolsPager", + "shortName": "list_tools" }, - "description": "Sample for ListSipTrunks", - "file": "dialogflow_v2beta1_generated_sip_trunks_list_sip_trunks_sync.py", + "description": "Sample for ListTools", + "file": "dialogflow_v2beta1_generated_tools_list_tools_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_SipTrunks_ListSipTrunks_sync", + "regionTag": "dialogflow_v2beta1_generated_Tools_ListTools_sync", "segments": [ { "end": 52, @@ -17603,33 +19225,33 @@ "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_sip_trunks_list_sip_trunks_sync.py" + "title": "dialogflow_v2beta1_generated_tools_list_tools_sync.py" }, { "canonical": true, "clientMethod": { "async": true, "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksAsyncClient", - "shortName": "SipTrunksAsyncClient" + "fullName": "google.cloud.dialogflow_v2beta1.ToolsAsyncClient", + "shortName": "ToolsAsyncClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksAsyncClient.update_sip_trunk", + "fullName": "google.cloud.dialogflow_v2beta1.ToolsAsyncClient.update_tool", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks.UpdateSipTrunk", + "fullName": "google.cloud.dialogflow.v2beta1.Tools.UpdateTool", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks", - "shortName": "SipTrunks" + "fullName": "google.cloud.dialogflow.v2beta1.Tools", + "shortName": "Tools" }, - "shortName": "UpdateSipTrunk" + "shortName": "UpdateTool" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.UpdateSipTrunkRequest" + "type": "google.cloud.dialogflow_v2beta1.types.UpdateToolRequest" }, { - "name": "sip_trunk", - "type": "google.cloud.dialogflow_v2beta1.types.SipTrunk" + "name": "tool", + "type": "google.cloud.dialogflow_v2beta1.types.Tool" }, { "name": "update_mask", @@ -17648,22 +19270,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.SipTrunk", - "shortName": "update_sip_trunk" + "resultType": "google.cloud.dialogflow_v2beta1.types.Tool", + "shortName": "update_tool" }, - "description": "Sample for UpdateSipTrunk", - "file": "dialogflow_v2beta1_generated_sip_trunks_update_sip_trunk_async.py", + "description": "Sample for UpdateTool", + "file": "dialogflow_v2beta1_generated_tools_update_tool_async.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_SipTrunks_UpdateSipTrunk_async", + "regionTag": "dialogflow_v2beta1_generated_Tools_UpdateTool_async", "segments": [ { - "end": 54, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 54, + "end": 55, "start": 27, "type": "SHORT" }, @@ -17673,47 +19295,47 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 48, + "end": 49, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 51, - "start": 49, + "end": 52, + "start": 50, "type": "REQUEST_EXECUTION" }, { - "end": 55, - "start": 52, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_sip_trunks_update_sip_trunk_async.py" + "title": "dialogflow_v2beta1_generated_tools_update_tool_async.py" }, { "canonical": true, "clientMethod": { "client": { - "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksClient", - "shortName": "SipTrunksClient" + "fullName": "google.cloud.dialogflow_v2beta1.ToolsClient", + "shortName": "ToolsClient" }, - "fullName": "google.cloud.dialogflow_v2beta1.SipTrunksClient.update_sip_trunk", + "fullName": "google.cloud.dialogflow_v2beta1.ToolsClient.update_tool", "method": { - "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks.UpdateSipTrunk", + "fullName": "google.cloud.dialogflow.v2beta1.Tools.UpdateTool", "service": { - "fullName": "google.cloud.dialogflow.v2beta1.SipTrunks", - "shortName": "SipTrunks" + "fullName": "google.cloud.dialogflow.v2beta1.Tools", + "shortName": "Tools" }, - "shortName": "UpdateSipTrunk" + "shortName": "UpdateTool" }, "parameters": [ { "name": "request", - "type": "google.cloud.dialogflow_v2beta1.types.UpdateSipTrunkRequest" + "type": "google.cloud.dialogflow_v2beta1.types.UpdateToolRequest" }, { - "name": "sip_trunk", - "type": "google.cloud.dialogflow_v2beta1.types.SipTrunk" + "name": "tool", + "type": "google.cloud.dialogflow_v2beta1.types.Tool" }, { "name": "update_mask", @@ -17732,22 +19354,22 @@ "type": "Sequence[Tuple[str, Union[str, bytes]]]" } ], - "resultType": "google.cloud.dialogflow_v2beta1.types.SipTrunk", - "shortName": "update_sip_trunk" + "resultType": "google.cloud.dialogflow_v2beta1.types.Tool", + "shortName": "update_tool" }, - "description": "Sample for UpdateSipTrunk", - "file": "dialogflow_v2beta1_generated_sip_trunks_update_sip_trunk_sync.py", + "description": "Sample for UpdateTool", + "file": "dialogflow_v2beta1_generated_tools_update_tool_sync.py", "language": "PYTHON", "origin": "API_DEFINITION", - "regionTag": "dialogflow_v2beta1_generated_SipTrunks_UpdateSipTrunk_sync", + "regionTag": "dialogflow_v2beta1_generated_Tools_UpdateTool_sync", "segments": [ { - "end": 54, + "end": 55, "start": 27, "type": "FULL" }, { - "end": 54, + "end": 55, "start": 27, "type": "SHORT" }, @@ -17757,22 +19379,22 @@ "type": "CLIENT_INITIALIZATION" }, { - "end": 48, + "end": 49, "start": 41, "type": "REQUEST_INITIALIZATION" }, { - "end": 51, - "start": 49, + "end": 52, + "start": 50, "type": "REQUEST_EXECUTION" }, { - "end": 55, - "start": 52, + "end": 56, + "start": 53, "type": "RESPONSE_HANDLING" } ], - "title": "dialogflow_v2beta1_generated_sip_trunks_update_sip_trunk_sync.py" + "title": "dialogflow_v2beta1_generated_tools_update_tool_sync.py" }, { "canonical": true, diff --git a/packages/google-cloud-dialogflow/scripts/fixup_dialogflow_v2beta1_keywords.py b/packages/google-cloud-dialogflow/scripts/fixup_dialogflow_v2beta1_keywords.py index 5c145a1b2e0b..08e74f98186c 100644 --- a/packages/google-cloud-dialogflow/scripts/fixup_dialogflow_v2beta1_keywords.py +++ b/packages/google-cloud-dialogflow/scripts/fixup_dialogflow_v2beta1_keywords.py @@ -48,6 +48,7 @@ class dialogflowCallTransformer(cst.CSTTransformer): 'batch_update_entities': ('parent', 'entities', 'language_code', 'update_mask', ), 'batch_update_entity_types': ('parent', 'entity_type_batch_uri', 'entity_type_batch_inline', 'language_code', 'update_mask', ), 'batch_update_intents': ('parent', 'intent_batch_uri', 'intent_batch_inline', 'language_code', 'update_mask', 'intent_view', ), + 'bidi_streaming_analyze_content': ('config', 'input', ), 'clear_suggestion_feature_config': ('conversation_profile', 'participant_role', 'suggestion_feature_type', ), 'compile_suggestion': ('parent', 'latest_message', 'context_size', ), 'complete_conversation': ('name', ), @@ -58,11 +59,13 @@ class dialogflowCallTransformer(cst.CSTTransformer): 'create_entity_type': ('parent', 'entity_type', 'language_code', ), 'create_environment': ('parent', 'environment', 'environment_id', ), 'create_generator': ('parent', 'generator', 'generator_id', ), + 'create_generator_evaluation': ('parent', 'generator_evaluation', ), 'create_intent': ('parent', 'intent', 'language_code', 'intent_view', ), 'create_knowledge_base': ('parent', 'knowledge_base', ), 'create_participant': ('parent', 'participant', ), 'create_session_entity_type': ('parent', 'session_entity_type', ), 'create_sip_trunk': ('parent', 'sip_trunk', ), + 'create_tool': ('parent', 'tool', 'tool_id', ), 'create_version': ('parent', 'version', ), 'delete_agent': ('parent', ), 'delete_all_contexts': ('parent', ), @@ -72,15 +75,17 @@ class dialogflowCallTransformer(cst.CSTTransformer): 'delete_entity_type': ('name', ), 'delete_environment': ('name', ), 'delete_generator': ('name', ), + 'delete_generator_evaluation': ('name', ), 'delete_intent': ('name', ), 'delete_knowledge_base': ('name', 'force', ), 'delete_phone_number': ('name', ), 'delete_session_entity_type': ('name', ), 'delete_sip_trunk': ('name', ), + 'delete_tool': ('name', ), 'delete_version': ('name', ), 'detect_intent': ('session', 'query_input', 'query_params', 'output_audio_config', 'output_audio_config_mask', 'input_audio', ), 'export_agent': ('parent', 'agent_uri', ), - 'generate_stateless_suggestion': ('parent', 'generator', 'generator_name', 'context_references', 'conversation_context', 'trigger_events', ), + 'generate_stateless_suggestion': ('parent', 'generator', 'generator_name', 'context_references', 'conversation_context', 'trigger_events', 'security_settings', ), 'generate_stateless_summary': ('stateless_conversation', 'conversation_profile', 'latest_message', 'max_context_size', ), 'generate_suggestions': ('conversation', 'latest_message', 'trigger_events', ), 'get_agent': ('parent', ), @@ -95,11 +100,13 @@ class dialogflowCallTransformer(cst.CSTTransformer): 'get_environment_history': ('parent', 'page_size', 'page_token', ), 'get_fulfillment': ('name', ), 'get_generator': ('name', ), + 'get_generator_evaluation': ('name', ), 'get_intent': ('name', 'language_code', 'intent_view', ), 'get_knowledge_base': ('name', ), 'get_participant': ('name', ), 'get_session_entity_type': ('name', ), 'get_sip_trunk': ('name', ), + 'get_tool': ('name', ), 'get_validation_result': ('parent', 'language_code', ), 'get_version': ('name', ), 'import_agent': ('parent', 'agent_uri', 'agent_content', ), @@ -113,6 +120,7 @@ class dialogflowCallTransformer(cst.CSTTransformer): 'list_documents': ('parent', 'page_size', 'page_token', 'filter', ), 'list_entity_types': ('parent', 'language_code', 'page_size', 'page_token', ), 'list_environments': ('parent', 'page_size', 'page_token', ), + 'list_generator_evaluations': ('parent', 'page_size', 'page_token', ), 'list_generators': ('parent', 'page_size', 'page_token', ), 'list_intents': ('parent', 'language_code', 'intent_view', 'page_size', 'page_token', ), 'list_knowledge_bases': ('parent', 'page_size', 'page_token', 'filter', ), @@ -122,6 +130,7 @@ class dialogflowCallTransformer(cst.CSTTransformer): 'list_session_entity_types': ('parent', 'page_size', 'page_token', ), 'list_sip_trunks': ('parent', 'page_size', 'page_token', ), 'list_suggestions': ('parent', 'page_size', 'page_token', 'filter', ), + 'list_tools': ('parent', 'page_size', 'page_token', ), 'list_versions': ('parent', 'page_size', 'page_token', ), 'reload_document': ('name', 'gcs_source', 'import_gcs_custom_metadata', ), 'restore_agent': ('parent', 'agent_uri', 'agent_content', ), @@ -152,6 +161,7 @@ class dialogflowCallTransformer(cst.CSTTransformer): 'update_phone_number': ('phone_number', 'update_mask', ), 'update_session_entity_type': ('session_entity_type', 'update_mask', ), 'update_sip_trunk': ('sip_trunk', 'update_mask', ), + 'update_tool': ('tool', 'update_mask', ), 'update_version': ('version', 'update_mask', ), } diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_answer_records.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_answer_records.py index 7998ed8e1b0f..dbc3f4eb3ee7 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_answer_records.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_answer_records.py @@ -63,8 +63,16 @@ pagers, transports, ) -from google.cloud.dialogflow_v2beta1.types import context, intent, participant, session +from google.cloud.dialogflow_v2beta1.types import ( + context, + generator, + intent, + participant, + session, + tool_call, +) from google.cloud.dialogflow_v2beta1.types import answer_record as gcd_answer_record +from google.cloud.dialogflow_v2beta1.types import agent_coaching_instruction from google.cloud.dialogflow_v2beta1.types import answer_record CRED_INFO_JSON = { @@ -3541,6 +3549,80 @@ def test_update_answer_record_rest_call_success(request_type): }, "answer_record": "answer_record_value", }, + "generator_suggestion": { + "free_form_suggestion": {"response": "response_value"}, + "summary_suggestion": { + "summary_sections": [ + {"section": "section_value", "summary": "summary_value"} + ] + }, + "agent_coaching_suggestion": { + "applicable_instructions": [ + { + "display_name": "display_name_value", + "display_details": "display_details_value", + "condition": "condition_value", + "agent_action": "agent_action_value", + "system_action": "system_action_value", + "duplicate_check_result": { + "duplicate_suggestions": [ + { + "answer_record": "answer_record_value", + "suggestion_index": 1727, + "similarity_score": 0.17300000000000001, + } + ] + }, + } + ], + "agent_action_suggestions": [ + { + "agent_action": "agent_action_value", + "sources": {"instruction_indexes": [2066, 2067]}, + "duplicate_check_result": { + "duplicate_suggestions": [ + { + "answer_record": "answer_record_value", + "sources": {}, + "suggestion_index": 1727, + "similarity_score": 0.17300000000000001, + } + ] + }, + } + ], + "sample_responses": [ + { + "response_text": "response_text_value", + "sources": {}, + "duplicate_check_result": {}, + } + ], + }, + "tool_call_info": [ + { + "tool_call": { + "tool": "tool_value", + "tool_display_name": "tool_display_name_value", + "tool_display_details": "tool_display_details_value", + "action": "action_value", + "input_parameters": {}, + "create_time": {}, + "answer_record": "answer_record_value", + "state": 1, + }, + "tool_call_result": { + "tool": "tool_value", + "action": "action_value", + "error": {"message": "message_value"}, + "raw_content": b"raw_content_blob", + "content": "content_value", + "create_time": {}, + "answer_record": "answer_record_value", + }, + } + ], + }, }, } # The version of a generated dependency at test runtime may differ from the version used during generation. @@ -4624,8 +4706,34 @@ def test_parse_intent_path(): assert expected == actual +def test_tool_path(): + project = "winkle" + location = "nautilus" + tool = "scallop" + expected = "projects/{project}/locations/{location}/tools/{tool}".format( + project=project, + location=location, + tool=tool, + ) + actual = AnswerRecordsClient.tool_path(project, location, tool) + assert expected == actual + + +def test_parse_tool_path(): + expected = { + "project": "abalone", + "location": "squid", + "tool": "clam", + } + path = AnswerRecordsClient.tool_path(**expected) + + # Check that the path construction is reversible. + actual = AnswerRecordsClient.parse_tool_path(path) + assert expected == actual + + def test_common_billing_account_path(): - billing_account = "winkle" + billing_account = "whelk" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -4635,7 +4743,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "nautilus", + "billing_account": "octopus", } path = AnswerRecordsClient.common_billing_account_path(**expected) @@ -4645,7 +4753,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "scallop" + folder = "oyster" expected = "folders/{folder}".format( folder=folder, ) @@ -4655,7 +4763,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "abalone", + "folder": "nudibranch", } path = AnswerRecordsClient.common_folder_path(**expected) @@ -4665,7 +4773,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "squid" + organization = "cuttlefish" expected = "organizations/{organization}".format( organization=organization, ) @@ -4675,7 +4783,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "clam", + "organization": "mussel", } path = AnswerRecordsClient.common_organization_path(**expected) @@ -4685,7 +4793,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "whelk" + project = "winkle" expected = "projects/{project}".format( project=project, ) @@ -4695,7 +4803,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "octopus", + "project": "nautilus", } path = AnswerRecordsClient.common_project_path(**expected) @@ -4705,8 +4813,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "oyster" - location = "nudibranch" + project = "scallop" + location = "abalone" expected = "projects/{project}/locations/{location}".format( project=project, location=location, @@ -4717,8 +4825,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "cuttlefish", - "location": "mussel", + "project": "squid", + "location": "clam", } path = AnswerRecordsClient.common_location_path(**expected) diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversation_profiles.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversation_profiles.py index 59762cb69260..b5eb57e9e00f 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversation_profiles.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversation_profiles.py @@ -77,7 +77,7 @@ ) from google.cloud.dialogflow_v2beta1.types import audio_config from google.cloud.dialogflow_v2beta1.types import conversation_profile -from google.cloud.dialogflow_v2beta1.types import participant +from google.cloud.dialogflow_v2beta1.types import generator, participant CRED_INFO_JSON = { "credential_source": "/path/to/file", @@ -6212,6 +6212,12 @@ def test_create_conversation_profile_rest_call_success(request_type): "enable_query_suggestion_when_no_answer": True, "enable_conversation_augmented_query": True, "enable_query_suggestion_only": True, + "enable_response_debug_info": True, + "rai_settings": { + "rai_category_configs": [ + {"category": 1, "sensitivity_level": 1} + ] + }, "suggestion_trigger_settings": { "no_small_talk": True, "only_end_user": True, @@ -6250,6 +6256,9 @@ def test_create_conversation_profile_rest_call_success(request_type): "group_suggestion_responses": True, "generators": ["generators_value1", "generators_value2"], "disable_high_latency_features_sync_delivery": True, + "skip_empty_event_based_suggestion": True, + "use_unredacted_conversation_data": True, + "enable_async_tool_call": True, }, "end_user_suggestion_config": {}, "message_analysis_config": { @@ -6292,6 +6301,13 @@ def test_create_conversation_profile_rest_call_success(request_type): "effects_profile_id_value2", ], "voice": {"name": "name_value", "ssml_gender": 1}, + "pronunciations": [ + { + "phrase": "phrase_value", + "phonetic_encoding": 1, + "pronunciation": "pronunciation_value", + } + ], }, } # The version of a generated dependency at test runtime may differ from the version used during generation. @@ -6536,6 +6552,12 @@ def test_update_conversation_profile_rest_call_success(request_type): "enable_query_suggestion_when_no_answer": True, "enable_conversation_augmented_query": True, "enable_query_suggestion_only": True, + "enable_response_debug_info": True, + "rai_settings": { + "rai_category_configs": [ + {"category": 1, "sensitivity_level": 1} + ] + }, "suggestion_trigger_settings": { "no_small_talk": True, "only_end_user": True, @@ -6574,6 +6596,9 @@ def test_update_conversation_profile_rest_call_success(request_type): "group_suggestion_responses": True, "generators": ["generators_value1", "generators_value2"], "disable_high_latency_features_sync_delivery": True, + "skip_empty_event_based_suggestion": True, + "use_unredacted_conversation_data": True, + "enable_async_tool_call": True, }, "end_user_suggestion_config": {}, "message_analysis_config": { @@ -6616,6 +6641,13 @@ def test_update_conversation_profile_rest_call_success(request_type): "effects_profile_id_value2", ], "voice": {"name": "name_value", "ssml_gender": 1}, + "pronunciations": [ + { + "phrase": "phrase_value", + "phonetic_encoding": 1, + "pronunciation": "pronunciation_value", + } + ], }, } # The version of a generated dependency at test runtime may differ from the version used during generation. diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversations.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversations.py index 3a0ad2c3d3ad..9c8d429d2e1a 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversations.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversations.py @@ -63,14 +63,18 @@ pagers, transports, ) +from google.cloud.dialogflow_v2beta1.types import ( + agent_coaching_instruction, + audio_config, +) from google.cloud.dialogflow_v2beta1.types import ( conversation_profile, generator, participant, session, + tool_call, ) from google.cloud.dialogflow_v2beta1.types import conversation as gcd_conversation -from google.cloud.dialogflow_v2beta1.types import audio_config from google.cloud.dialogflow_v2beta1.types import conversation CRED_INFO_JSON = { @@ -4681,6 +4685,7 @@ def test_generate_stateless_suggestion_non_empty_request_with_auto_populated_fie request = conversation.GenerateStatelessSuggestionRequest( parent="parent_value", generator_name="generator_name_value", + security_settings="security_settings_value", ) # Mock the actual call within the gRPC stub, and fake the request. @@ -4696,6 +4701,7 @@ def test_generate_stateless_suggestion_non_empty_request_with_auto_populated_fie assert args[0] == conversation.GenerateStatelessSuggestionRequest( parent="parent_value", generator_name="generator_name_value", + security_settings="security_settings_value", ) @@ -11531,8 +11537,34 @@ def test_parse_phrase_set_path(): assert expected == actual +def test_tool_path(): + project = "whelk" + location = "octopus" + tool = "oyster" + expected = "projects/{project}/locations/{location}/tools/{tool}".format( + project=project, + location=location, + tool=tool, + ) + actual = ConversationsClient.tool_path(project, location, tool) + assert expected == actual + + +def test_parse_tool_path(): + expected = { + "project": "nudibranch", + "location": "cuttlefish", + "tool": "mussel", + } + path = ConversationsClient.tool_path(**expected) + + # Check that the path construction is reversible. + actual = ConversationsClient.parse_tool_path(path) + assert expected == actual + + def test_common_billing_account_path(): - billing_account = "whelk" + billing_account = "winkle" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -11542,7 +11574,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "octopus", + "billing_account": "nautilus", } path = ConversationsClient.common_billing_account_path(**expected) @@ -11552,7 +11584,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "oyster" + folder = "scallop" expected = "folders/{folder}".format( folder=folder, ) @@ -11562,7 +11594,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "nudibranch", + "folder": "abalone", } path = ConversationsClient.common_folder_path(**expected) @@ -11572,7 +11604,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "cuttlefish" + organization = "squid" expected = "organizations/{organization}".format( organization=organization, ) @@ -11582,7 +11614,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "mussel", + "organization": "clam", } path = ConversationsClient.common_organization_path(**expected) @@ -11592,7 +11624,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "winkle" + project = "whelk" expected = "projects/{project}".format( project=project, ) @@ -11602,7 +11634,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "nautilus", + "project": "octopus", } path = ConversationsClient.common_project_path(**expected) @@ -11612,8 +11644,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "scallop" - location = "abalone" + project = "oyster" + location = "nudibranch" expected = "projects/{project}/locations/{location}".format( project=project, location=location, @@ -11624,8 +11656,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "squid", - "location": "clam", + "project": "cuttlefish", + "location": "mussel", } path = ConversationsClient.common_location_path(**expected) diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_generator_evaluations.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_generator_evaluations.py new file mode 100644 index 000000000000..5190fad5122e --- /dev/null +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_generator_evaluations.py @@ -0,0 +1,6714 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import ( + future, + gapic_v1, + grpc_helpers, + grpc_helpers_async, + operation, + operations_v1, + path_template, +) +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import operation_async # type: ignore +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.location import locations_pb2 +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import any_pb2 # type: ignore +from google.protobuf import struct_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + +from google.cloud.dialogflow_v2beta1.services.generator_evaluations import ( + GeneratorEvaluationsAsyncClient, + GeneratorEvaluationsClient, + pagers, + transports, +) +from google.cloud.dialogflow_v2beta1.types import agent_coaching_instruction, generator +from google.cloud.dialogflow_v2beta1.types import ( + generator_evaluation as gcd_generator_evaluation, +) +from google.cloud.dialogflow_v2beta1.types import generator_evaluation +from google.cloud.dialogflow_v2beta1.types import operations, tool_call + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert GeneratorEvaluationsClient._get_default_mtls_endpoint(None) is None + assert ( + GeneratorEvaluationsClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + GeneratorEvaluationsClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + GeneratorEvaluationsClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + GeneratorEvaluationsClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + GeneratorEvaluationsClient._get_default_mtls_endpoint(non_googleapi) + == non_googleapi + ) + + +def test__read_environment_variables(): + assert GeneratorEvaluationsClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert GeneratorEvaluationsClient._read_environment_variables() == ( + True, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert GeneratorEvaluationsClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + GeneratorEvaluationsClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert GeneratorEvaluationsClient._read_environment_variables() == ( + False, + "never", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert GeneratorEvaluationsClient._read_environment_variables() == ( + False, + "always", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert GeneratorEvaluationsClient._read_environment_variables() == ( + False, + "auto", + None, + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + GeneratorEvaluationsClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert GeneratorEvaluationsClient._read_environment_variables() == ( + False, + "auto", + "foo.com", + ) + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert GeneratorEvaluationsClient._get_client_cert_source(None, False) is None + assert ( + GeneratorEvaluationsClient._get_client_cert_source( + mock_provided_cert_source, False + ) + is None + ) + assert ( + GeneratorEvaluationsClient._get_client_cert_source( + mock_provided_cert_source, True + ) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + GeneratorEvaluationsClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + GeneratorEvaluationsClient._get_client_cert_source( + mock_provided_cert_source, "true" + ) + is mock_provided_cert_source + ) + + +@mock.patch.object( + GeneratorEvaluationsClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(GeneratorEvaluationsClient), +) +@mock.patch.object( + GeneratorEvaluationsAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(GeneratorEvaluationsAsyncClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = GeneratorEvaluationsClient._DEFAULT_UNIVERSE + default_endpoint = GeneratorEvaluationsClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = GeneratorEvaluationsClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + GeneratorEvaluationsClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + GeneratorEvaluationsClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == GeneratorEvaluationsClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + GeneratorEvaluationsClient._get_api_endpoint( + None, None, default_universe, "auto" + ) + == default_endpoint + ) + assert ( + GeneratorEvaluationsClient._get_api_endpoint( + None, None, default_universe, "always" + ) + == GeneratorEvaluationsClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + GeneratorEvaluationsClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == GeneratorEvaluationsClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + GeneratorEvaluationsClient._get_api_endpoint(None, None, mock_universe, "never") + == mock_endpoint + ) + assert ( + GeneratorEvaluationsClient._get_api_endpoint( + None, None, default_universe, "never" + ) + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + GeneratorEvaluationsClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + GeneratorEvaluationsClient._get_universe_domain( + client_universe_domain, universe_domain_env + ) + == client_universe_domain + ) + assert ( + GeneratorEvaluationsClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ( + GeneratorEvaluationsClient._get_universe_domain(None, None) + == GeneratorEvaluationsClient._DEFAULT_UNIVERSE + ) + + with pytest.raises(ValueError) as excinfo: + GeneratorEvaluationsClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = GeneratorEvaluationsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = GeneratorEvaluationsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (GeneratorEvaluationsClient, "grpc"), + (GeneratorEvaluationsAsyncClient, "grpc_asyncio"), + (GeneratorEvaluationsClient, "rest"), + ], +) +def test_generator_evaluations_client_from_service_account_info( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "dialogflow.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://dialogflow.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.GeneratorEvaluationsGrpcTransport, "grpc"), + (transports.GeneratorEvaluationsGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.GeneratorEvaluationsRestTransport, "rest"), + ], +) +def test_generator_evaluations_client_service_account_always_use_jwt( + transport_class, transport_name +): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (GeneratorEvaluationsClient, "grpc"), + (GeneratorEvaluationsAsyncClient, "grpc_asyncio"), + (GeneratorEvaluationsClient, "rest"), + ], +) +def test_generator_evaluations_client_from_service_account_file( + client_class, transport_name +): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "dialogflow.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://dialogflow.googleapis.com" + ) + + +def test_generator_evaluations_client_get_transport_class(): + transport = GeneratorEvaluationsClient.get_transport_class() + available_transports = [ + transports.GeneratorEvaluationsGrpcTransport, + transports.GeneratorEvaluationsRestTransport, + ] + assert transport in available_transports + + transport = GeneratorEvaluationsClient.get_transport_class("grpc") + assert transport == transports.GeneratorEvaluationsGrpcTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + GeneratorEvaluationsClient, + transports.GeneratorEvaluationsGrpcTransport, + "grpc", + ), + ( + GeneratorEvaluationsAsyncClient, + transports.GeneratorEvaluationsGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ( + GeneratorEvaluationsClient, + transports.GeneratorEvaluationsRestTransport, + "rest", + ), + ], +) +@mock.patch.object( + GeneratorEvaluationsClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(GeneratorEvaluationsClient), +) +@mock.patch.object( + GeneratorEvaluationsAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(GeneratorEvaluationsAsyncClient), +) +def test_generator_evaluations_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(GeneratorEvaluationsClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(GeneratorEvaluationsClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + ( + GeneratorEvaluationsClient, + transports.GeneratorEvaluationsGrpcTransport, + "grpc", + "true", + ), + ( + GeneratorEvaluationsAsyncClient, + transports.GeneratorEvaluationsGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + ( + GeneratorEvaluationsClient, + transports.GeneratorEvaluationsGrpcTransport, + "grpc", + "false", + ), + ( + GeneratorEvaluationsAsyncClient, + transports.GeneratorEvaluationsGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + ( + GeneratorEvaluationsClient, + transports.GeneratorEvaluationsRestTransport, + "rest", + "true", + ), + ( + GeneratorEvaluationsClient, + transports.GeneratorEvaluationsRestTransport, + "rest", + "false", + ), + ], +) +@mock.patch.object( + GeneratorEvaluationsClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(GeneratorEvaluationsClient), +) +@mock.patch.object( + GeneratorEvaluationsAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(GeneratorEvaluationsAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_generator_evaluations_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class", [GeneratorEvaluationsClient, GeneratorEvaluationsAsyncClient] +) +@mock.patch.object( + GeneratorEvaluationsClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(GeneratorEvaluationsClient), +) +@mock.patch.object( + GeneratorEvaluationsAsyncClient, + "DEFAULT_ENDPOINT", + modify_default_endpoint(GeneratorEvaluationsAsyncClient), +) +def test_generator_evaluations_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize( + "client_class", [GeneratorEvaluationsClient, GeneratorEvaluationsAsyncClient] +) +@mock.patch.object( + GeneratorEvaluationsClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(GeneratorEvaluationsClient), +) +@mock.patch.object( + GeneratorEvaluationsAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(GeneratorEvaluationsAsyncClient), +) +def test_generator_evaluations_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = GeneratorEvaluationsClient._DEFAULT_UNIVERSE + default_endpoint = GeneratorEvaluationsClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = GeneratorEvaluationsClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + ( + GeneratorEvaluationsClient, + transports.GeneratorEvaluationsGrpcTransport, + "grpc", + ), + ( + GeneratorEvaluationsAsyncClient, + transports.GeneratorEvaluationsGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ( + GeneratorEvaluationsClient, + transports.GeneratorEvaluationsRestTransport, + "rest", + ), + ], +) +def test_generator_evaluations_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + GeneratorEvaluationsClient, + transports.GeneratorEvaluationsGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + GeneratorEvaluationsAsyncClient, + transports.GeneratorEvaluationsGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ( + GeneratorEvaluationsClient, + transports.GeneratorEvaluationsRestTransport, + "rest", + None, + ), + ], +) +def test_generator_evaluations_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_generator_evaluations_client_client_options_from_dict(): + with mock.patch( + "google.cloud.dialogflow_v2beta1.services.generator_evaluations.transports.GeneratorEvaluationsGrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = GeneratorEvaluationsClient( + client_options={"api_endpoint": "squid.clam.whelk"} + ) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + ( + GeneratorEvaluationsClient, + transports.GeneratorEvaluationsGrpcTransport, + "grpc", + grpc_helpers, + ), + ( + GeneratorEvaluationsAsyncClient, + transports.GeneratorEvaluationsGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ], +) +def test_generator_evaluations_client_create_channel_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel" + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "dialogflow.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/dialogflow", + ), + scopes=None, + default_host="dialogflow.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "request_type", + [ + gcd_generator_evaluation.CreateGeneratorEvaluationRequest, + dict, + ], +) +def test_create_generator_evaluation(request_type, transport: str = "grpc"): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_generator_evaluation), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.create_generator_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = gcd_generator_evaluation.CreateGeneratorEvaluationRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_create_generator_evaluation_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = gcd_generator_evaluation.CreateGeneratorEvaluationRequest( + parent="parent_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_generator_evaluation), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.create_generator_evaluation(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == gcd_generator_evaluation.CreateGeneratorEvaluationRequest( + parent="parent_value", + ) + + +def test_create_generator_evaluation_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.create_generator_evaluation + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.create_generator_evaluation + ] = mock_rpc + request = {} + client.create_generator_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.create_generator_evaluation(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_create_generator_evaluation_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.create_generator_evaluation + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.create_generator_evaluation + ] = mock_rpc + + request = {} + await client.create_generator_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods call wrapper_fn to build a cached + # client._transport.operations_client instance on first rpc call. + # Subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + await client.create_generator_evaluation(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_create_generator_evaluation_async( + transport: str = "grpc_asyncio", + request_type=gcd_generator_evaluation.CreateGeneratorEvaluationRequest, +): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_generator_evaluation), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.create_generator_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = gcd_generator_evaluation.CreateGeneratorEvaluationRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_create_generator_evaluation_async_from_dict(): + await test_create_generator_evaluation_async(request_type=dict) + + +def test_create_generator_evaluation_field_headers(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = gcd_generator_evaluation.CreateGeneratorEvaluationRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_generator_evaluation), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_generator_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_create_generator_evaluation_field_headers_async(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = gcd_generator_evaluation.CreateGeneratorEvaluationRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_generator_evaluation), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.create_generator_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_create_generator_evaluation_flattened(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_generator_evaluation), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_generator_evaluation( + parent="parent_value", + generator_evaluation=gcd_generator_evaluation.GeneratorEvaluation( + name="name_value" + ), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].generator_evaluation + mock_val = gcd_generator_evaluation.GeneratorEvaluation(name="name_value") + assert arg == mock_val + + +def test_create_generator_evaluation_flattened_error(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_generator_evaluation( + gcd_generator_evaluation.CreateGeneratorEvaluationRequest(), + parent="parent_value", + generator_evaluation=gcd_generator_evaluation.GeneratorEvaluation( + name="name_value" + ), + ) + + +@pytest.mark.asyncio +async def test_create_generator_evaluation_flattened_async(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_generator_evaluation), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/op") + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_generator_evaluation( + parent="parent_value", + generator_evaluation=gcd_generator_evaluation.GeneratorEvaluation( + name="name_value" + ), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].generator_evaluation + mock_val = gcd_generator_evaluation.GeneratorEvaluation(name="name_value") + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_create_generator_evaluation_flattened_error_async(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_generator_evaluation( + gcd_generator_evaluation.CreateGeneratorEvaluationRequest(), + parent="parent_value", + generator_evaluation=gcd_generator_evaluation.GeneratorEvaluation( + name="name_value" + ), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + generator_evaluation.GetGeneratorEvaluationRequest, + dict, + ], +) +def test_get_generator_evaluation(request_type, transport: str = "grpc"): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_generator_evaluation), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = generator_evaluation.GeneratorEvaluation( + name="name_value", + display_name="display_name_value", + satisfies_pzs=True, + satisfies_pzi=True, + ) + response = client.get_generator_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = generator_evaluation.GetGeneratorEvaluationRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, generator_evaluation.GeneratorEvaluation) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.satisfies_pzs is True + assert response.satisfies_pzi is True + + +def test_get_generator_evaluation_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = generator_evaluation.GetGeneratorEvaluationRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_generator_evaluation), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.get_generator_evaluation(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == generator_evaluation.GetGeneratorEvaluationRequest( + name="name_value", + ) + + +def test_get_generator_evaluation_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_generator_evaluation + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_generator_evaluation + ] = mock_rpc + request = {} + client.get_generator_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_generator_evaluation(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_get_generator_evaluation_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.get_generator_evaluation + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.get_generator_evaluation + ] = mock_rpc + + request = {} + await client.get_generator_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.get_generator_evaluation(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_get_generator_evaluation_async( + transport: str = "grpc_asyncio", + request_type=generator_evaluation.GetGeneratorEvaluationRequest, +): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_generator_evaluation), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + generator_evaluation.GeneratorEvaluation( + name="name_value", + display_name="display_name_value", + satisfies_pzs=True, + satisfies_pzi=True, + ) + ) + response = await client.get_generator_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = generator_evaluation.GetGeneratorEvaluationRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, generator_evaluation.GeneratorEvaluation) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.satisfies_pzs is True + assert response.satisfies_pzi is True + + +@pytest.mark.asyncio +async def test_get_generator_evaluation_async_from_dict(): + await test_get_generator_evaluation_async(request_type=dict) + + +def test_get_generator_evaluation_field_headers(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = generator_evaluation.GetGeneratorEvaluationRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_generator_evaluation), "__call__" + ) as call: + call.return_value = generator_evaluation.GeneratorEvaluation() + client.get_generator_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_generator_evaluation_field_headers_async(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = generator_evaluation.GetGeneratorEvaluationRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_generator_evaluation), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + generator_evaluation.GeneratorEvaluation() + ) + await client.get_generator_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_get_generator_evaluation_flattened(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_generator_evaluation), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = generator_evaluation.GeneratorEvaluation() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_generator_evaluation( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_get_generator_evaluation_flattened_error(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_generator_evaluation( + generator_evaluation.GetGeneratorEvaluationRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_generator_evaluation_flattened_async(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_generator_evaluation), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = generator_evaluation.GeneratorEvaluation() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + generator_evaluation.GeneratorEvaluation() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_generator_evaluation( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_get_generator_evaluation_flattened_error_async(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_generator_evaluation( + generator_evaluation.GetGeneratorEvaluationRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + generator_evaluation.ListGeneratorEvaluationsRequest, + dict, + ], +) +def test_list_generator_evaluations(request_type, transport: str = "grpc"): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_generator_evaluations), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = generator_evaluation.ListGeneratorEvaluationsResponse( + next_page_token="next_page_token_value", + ) + response = client.list_generator_evaluations(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = generator_evaluation.ListGeneratorEvaluationsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListGeneratorEvaluationsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_generator_evaluations_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = generator_evaluation.ListGeneratorEvaluationsRequest( + parent="parent_value", + page_token="page_token_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_generator_evaluations), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.list_generator_evaluations(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == generator_evaluation.ListGeneratorEvaluationsRequest( + parent="parent_value", + page_token="page_token_value", + ) + + +def test_list_generator_evaluations_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_generator_evaluations + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_generator_evaluations + ] = mock_rpc + request = {} + client.list_generator_evaluations(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_generator_evaluations(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_list_generator_evaluations_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.list_generator_evaluations + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.list_generator_evaluations + ] = mock_rpc + + request = {} + await client.list_generator_evaluations(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.list_generator_evaluations(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_list_generator_evaluations_async( + transport: str = "grpc_asyncio", + request_type=generator_evaluation.ListGeneratorEvaluationsRequest, +): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_generator_evaluations), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + generator_evaluation.ListGeneratorEvaluationsResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.list_generator_evaluations(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = generator_evaluation.ListGeneratorEvaluationsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListGeneratorEvaluationsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_list_generator_evaluations_async_from_dict(): + await test_list_generator_evaluations_async(request_type=dict) + + +def test_list_generator_evaluations_field_headers(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = generator_evaluation.ListGeneratorEvaluationsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_generator_evaluations), "__call__" + ) as call: + call.return_value = generator_evaluation.ListGeneratorEvaluationsResponse() + client.list_generator_evaluations(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_generator_evaluations_field_headers_async(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = generator_evaluation.ListGeneratorEvaluationsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_generator_evaluations), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + generator_evaluation.ListGeneratorEvaluationsResponse() + ) + await client.list_generator_evaluations(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_list_generator_evaluations_flattened(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_generator_evaluations), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = generator_evaluation.ListGeneratorEvaluationsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_generator_evaluations( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +def test_list_generator_evaluations_flattened_error(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_generator_evaluations( + generator_evaluation.ListGeneratorEvaluationsRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_generator_evaluations_flattened_async(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_generator_evaluations), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = generator_evaluation.ListGeneratorEvaluationsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + generator_evaluation.ListGeneratorEvaluationsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_generator_evaluations( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_list_generator_evaluations_flattened_error_async(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_generator_evaluations( + generator_evaluation.ListGeneratorEvaluationsRequest(), + parent="parent_value", + ) + + +def test_list_generator_evaluations_pager(transport_name: str = "grpc"): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_generator_evaluations), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + generator_evaluation.ListGeneratorEvaluationsResponse( + generator_evaluations=[ + generator_evaluation.GeneratorEvaluation(), + generator_evaluation.GeneratorEvaluation(), + generator_evaluation.GeneratorEvaluation(), + ], + next_page_token="abc", + ), + generator_evaluation.ListGeneratorEvaluationsResponse( + generator_evaluations=[], + next_page_token="def", + ), + generator_evaluation.ListGeneratorEvaluationsResponse( + generator_evaluations=[ + generator_evaluation.GeneratorEvaluation(), + ], + next_page_token="ghi", + ), + generator_evaluation.ListGeneratorEvaluationsResponse( + generator_evaluations=[ + generator_evaluation.GeneratorEvaluation(), + generator_evaluation.GeneratorEvaluation(), + ], + ), + RuntimeError, + ) + + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_generator_evaluations( + request={}, retry=retry, timeout=timeout + ) + + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, generator_evaluation.GeneratorEvaluation) for i in results + ) + + +def test_list_generator_evaluations_pages(transport_name: str = "grpc"): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_generator_evaluations), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + generator_evaluation.ListGeneratorEvaluationsResponse( + generator_evaluations=[ + generator_evaluation.GeneratorEvaluation(), + generator_evaluation.GeneratorEvaluation(), + generator_evaluation.GeneratorEvaluation(), + ], + next_page_token="abc", + ), + generator_evaluation.ListGeneratorEvaluationsResponse( + generator_evaluations=[], + next_page_token="def", + ), + generator_evaluation.ListGeneratorEvaluationsResponse( + generator_evaluations=[ + generator_evaluation.GeneratorEvaluation(), + ], + next_page_token="ghi", + ), + generator_evaluation.ListGeneratorEvaluationsResponse( + generator_evaluations=[ + generator_evaluation.GeneratorEvaluation(), + generator_evaluation.GeneratorEvaluation(), + ], + ), + RuntimeError, + ) + pages = list(client.list_generator_evaluations(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_generator_evaluations_async_pager(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_generator_evaluations), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + generator_evaluation.ListGeneratorEvaluationsResponse( + generator_evaluations=[ + generator_evaluation.GeneratorEvaluation(), + generator_evaluation.GeneratorEvaluation(), + generator_evaluation.GeneratorEvaluation(), + ], + next_page_token="abc", + ), + generator_evaluation.ListGeneratorEvaluationsResponse( + generator_evaluations=[], + next_page_token="def", + ), + generator_evaluation.ListGeneratorEvaluationsResponse( + generator_evaluations=[ + generator_evaluation.GeneratorEvaluation(), + ], + next_page_token="ghi", + ), + generator_evaluation.ListGeneratorEvaluationsResponse( + generator_evaluations=[ + generator_evaluation.GeneratorEvaluation(), + generator_evaluation.GeneratorEvaluation(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_generator_evaluations( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all( + isinstance(i, generator_evaluation.GeneratorEvaluation) for i in responses + ) + + +@pytest.mark.asyncio +async def test_list_generator_evaluations_async_pages(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_generator_evaluations), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + generator_evaluation.ListGeneratorEvaluationsResponse( + generator_evaluations=[ + generator_evaluation.GeneratorEvaluation(), + generator_evaluation.GeneratorEvaluation(), + generator_evaluation.GeneratorEvaluation(), + ], + next_page_token="abc", + ), + generator_evaluation.ListGeneratorEvaluationsResponse( + generator_evaluations=[], + next_page_token="def", + ), + generator_evaluation.ListGeneratorEvaluationsResponse( + generator_evaluations=[ + generator_evaluation.GeneratorEvaluation(), + ], + next_page_token="ghi", + ), + generator_evaluation.ListGeneratorEvaluationsResponse( + generator_evaluations=[ + generator_evaluation.GeneratorEvaluation(), + generator_evaluation.GeneratorEvaluation(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_generator_evaluations(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + generator_evaluation.DeleteGeneratorEvaluationRequest, + dict, + ], +) +def test_delete_generator_evaluation(request_type, transport: str = "grpc"): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_generator_evaluation), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_generator_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = generator_evaluation.DeleteGeneratorEvaluationRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_generator_evaluation_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = generator_evaluation.DeleteGeneratorEvaluationRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_generator_evaluation), "__call__" + ) as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.delete_generator_evaluation(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == generator_evaluation.DeleteGeneratorEvaluationRequest( + name="name_value", + ) + + +def test_delete_generator_evaluation_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.delete_generator_evaluation + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.delete_generator_evaluation + ] = mock_rpc + request = {} + client.delete_generator_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.delete_generator_evaluation(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_delete_generator_evaluation_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.delete_generator_evaluation + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.delete_generator_evaluation + ] = mock_rpc + + request = {} + await client.delete_generator_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.delete_generator_evaluation(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_delete_generator_evaluation_async( + transport: str = "grpc_asyncio", + request_type=generator_evaluation.DeleteGeneratorEvaluationRequest, +): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_generator_evaluation), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_generator_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = generator_evaluation.DeleteGeneratorEvaluationRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_generator_evaluation_async_from_dict(): + await test_delete_generator_evaluation_async(request_type=dict) + + +def test_delete_generator_evaluation_field_headers(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = generator_evaluation.DeleteGeneratorEvaluationRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_generator_evaluation), "__call__" + ) as call: + call.return_value = None + client.delete_generator_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_delete_generator_evaluation_field_headers_async(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = generator_evaluation.DeleteGeneratorEvaluationRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_generator_evaluation), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_generator_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_delete_generator_evaluation_flattened(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_generator_evaluation), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_generator_evaluation( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_delete_generator_evaluation_flattened_error(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_generator_evaluation( + generator_evaluation.DeleteGeneratorEvaluationRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_delete_generator_evaluation_flattened_async(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_generator_evaluation), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_generator_evaluation( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_delete_generator_evaluation_flattened_error_async(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_generator_evaluation( + generator_evaluation.DeleteGeneratorEvaluationRequest(), + name="name_value", + ) + + +def test_create_generator_evaluation_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.create_generator_evaluation + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.create_generator_evaluation + ] = mock_rpc + + request = {} + client.create_generator_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + # Operation methods build a cached wrapper on first rpc call + # subsequent calls should use the cached wrapper + wrapper_fn.reset_mock() + + client.create_generator_evaluation(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_generator_evaluation_rest_required_fields( + request_type=gcd_generator_evaluation.CreateGeneratorEvaluationRequest, +): + transport_class = transports.GeneratorEvaluationsRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_generator_evaluation._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_generator_evaluation._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.create_generator_evaluation(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_create_generator_evaluation_rest_unset_required_fields(): + transport = transports.GeneratorEvaluationsRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_generator_evaluation._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "generatorEvaluation", + ) + ) + ) + + +def test_create_generator_evaluation_rest_flattened(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "parent": "projects/sample1/locations/sample2/generators/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + generator_evaluation=gcd_generator_evaluation.GeneratorEvaluation( + name="name_value" + ), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.create_generator_evaluation(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2beta1/{parent=projects/*/locations/*/generators/*}/evaluations" + % client.transport._host, + args[1], + ) + + +def test_create_generator_evaluation_rest_flattened_error(transport: str = "rest"): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_generator_evaluation( + gcd_generator_evaluation.CreateGeneratorEvaluationRequest(), + parent="parent_value", + generator_evaluation=gcd_generator_evaluation.GeneratorEvaluation( + name="name_value" + ), + ) + + +def test_get_generator_evaluation_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.get_generator_evaluation + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.get_generator_evaluation + ] = mock_rpc + + request = {} + client.get_generator_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_generator_evaluation(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_generator_evaluation_rest_required_fields( + request_type=generator_evaluation.GetGeneratorEvaluationRequest, +): + transport_class = transports.GeneratorEvaluationsRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_generator_evaluation._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_generator_evaluation._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = generator_evaluation.GeneratorEvaluation() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = generator_evaluation.GeneratorEvaluation.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_generator_evaluation(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_generator_evaluation_rest_unset_required_fields(): + transport = transports.GeneratorEvaluationsRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_generator_evaluation._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_generator_evaluation_rest_flattened(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = generator_evaluation.GeneratorEvaluation() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/generators/sample3/evaluations/sample4" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = generator_evaluation.GeneratorEvaluation.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_generator_evaluation(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2beta1/{name=projects/*/locations/*/generators/*/evaluations/*}" + % client.transport._host, + args[1], + ) + + +def test_get_generator_evaluation_rest_flattened_error(transport: str = "rest"): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_generator_evaluation( + generator_evaluation.GetGeneratorEvaluationRequest(), + name="name_value", + ) + + +def test_list_generator_evaluations_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.list_generator_evaluations + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.list_generator_evaluations + ] = mock_rpc + + request = {} + client.list_generator_evaluations(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_generator_evaluations(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_generator_evaluations_rest_required_fields( + request_type=generator_evaluation.ListGeneratorEvaluationsRequest, +): + transport_class = transports.GeneratorEvaluationsRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_generator_evaluations._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_generator_evaluations._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = generator_evaluation.ListGeneratorEvaluationsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = generator_evaluation.ListGeneratorEvaluationsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_generator_evaluations(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_generator_evaluations_rest_unset_required_fields(): + transport = transports.GeneratorEvaluationsRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_generator_evaluations._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_generator_evaluations_rest_flattened(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = generator_evaluation.ListGeneratorEvaluationsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = { + "parent": "projects/sample1/locations/sample2/generators/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = generator_evaluation.ListGeneratorEvaluationsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_generator_evaluations(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2beta1/{parent=projects/*/locations/*/generators/*}/evaluations" + % client.transport._host, + args[1], + ) + + +def test_list_generator_evaluations_rest_flattened_error(transport: str = "rest"): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_generator_evaluations( + generator_evaluation.ListGeneratorEvaluationsRequest(), + parent="parent_value", + ) + + +def test_list_generator_evaluations_rest_pager(transport: str = "rest"): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + generator_evaluation.ListGeneratorEvaluationsResponse( + generator_evaluations=[ + generator_evaluation.GeneratorEvaluation(), + generator_evaluation.GeneratorEvaluation(), + generator_evaluation.GeneratorEvaluation(), + ], + next_page_token="abc", + ), + generator_evaluation.ListGeneratorEvaluationsResponse( + generator_evaluations=[], + next_page_token="def", + ), + generator_evaluation.ListGeneratorEvaluationsResponse( + generator_evaluations=[ + generator_evaluation.GeneratorEvaluation(), + ], + next_page_token="ghi", + ), + generator_evaluation.ListGeneratorEvaluationsResponse( + generator_evaluations=[ + generator_evaluation.GeneratorEvaluation(), + generator_evaluation.GeneratorEvaluation(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + generator_evaluation.ListGeneratorEvaluationsResponse.to_json(x) + for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = { + "parent": "projects/sample1/locations/sample2/generators/sample3" + } + + pager = client.list_generator_evaluations(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all( + isinstance(i, generator_evaluation.GeneratorEvaluation) for i in results + ) + + pages = list(client.list_generator_evaluations(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_delete_generator_evaluation_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.delete_generator_evaluation + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.delete_generator_evaluation + ] = mock_rpc + + request = {} + client.delete_generator_evaluation(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.delete_generator_evaluation(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_delete_generator_evaluation_rest_required_fields( + request_type=generator_evaluation.DeleteGeneratorEvaluationRequest, +): + transport_class = transports.GeneratorEvaluationsRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_generator_evaluation._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_generator_evaluation._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.delete_generator_evaluation(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_delete_generator_evaluation_rest_unset_required_fields(): + transport = transports.GeneratorEvaluationsRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_generator_evaluation._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_delete_generator_evaluation_rest_flattened(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/locations/sample2/generators/sample3/evaluations/sample4" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.delete_generator_evaluation(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2beta1/{name=projects/*/locations/*/generators/*/evaluations/*}" + % client.transport._host, + args[1], + ) + + +def test_delete_generator_evaluation_rest_flattened_error(transport: str = "rest"): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_generator_evaluation( + generator_evaluation.DeleteGeneratorEvaluationRequest(), + name="name_value", + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.GeneratorEvaluationsGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.GeneratorEvaluationsGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = GeneratorEvaluationsClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.GeneratorEvaluationsGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = GeneratorEvaluationsClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = GeneratorEvaluationsClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.GeneratorEvaluationsGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = GeneratorEvaluationsClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.GeneratorEvaluationsGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = GeneratorEvaluationsClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.GeneratorEvaluationsGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.GeneratorEvaluationsGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.GeneratorEvaluationsGrpcTransport, + transports.GeneratorEvaluationsGrpcAsyncIOTransport, + transports.GeneratorEvaluationsRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = GeneratorEvaluationsClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_generator_evaluation_empty_call_grpc(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_generator_evaluation), "__call__" + ) as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.create_generator_evaluation(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcd_generator_evaluation.CreateGeneratorEvaluationRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_generator_evaluation_empty_call_grpc(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_generator_evaluation), "__call__" + ) as call: + call.return_value = generator_evaluation.GeneratorEvaluation() + client.get_generator_evaluation(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = generator_evaluation.GetGeneratorEvaluationRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_generator_evaluations_empty_call_grpc(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_generator_evaluations), "__call__" + ) as call: + call.return_value = generator_evaluation.ListGeneratorEvaluationsResponse() + client.list_generator_evaluations(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = generator_evaluation.ListGeneratorEvaluationsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_generator_evaluation_empty_call_grpc(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_generator_evaluation), "__call__" + ) as call: + call.return_value = None + client.delete_generator_evaluation(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = generator_evaluation.DeleteGeneratorEvaluationRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = GeneratorEvaluationsAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_generator_evaluation_empty_call_grpc_asyncio(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_generator_evaluation), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + await client.create_generator_evaluation(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcd_generator_evaluation.CreateGeneratorEvaluationRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_generator_evaluation_empty_call_grpc_asyncio(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_generator_evaluation), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + generator_evaluation.GeneratorEvaluation( + name="name_value", + display_name="display_name_value", + satisfies_pzs=True, + satisfies_pzi=True, + ) + ) + await client.get_generator_evaluation(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = generator_evaluation.GetGeneratorEvaluationRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_generator_evaluations_empty_call_grpc_asyncio(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_generator_evaluations), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + generator_evaluation.ListGeneratorEvaluationsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_generator_evaluations(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = generator_evaluation.ListGeneratorEvaluationsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_generator_evaluation_empty_call_grpc_asyncio(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_generator_evaluation), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_generator_evaluation(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = generator_evaluation.DeleteGeneratorEvaluationRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = GeneratorEvaluationsClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_create_generator_evaluation_rest_bad_request( + request_type=gcd_generator_evaluation.CreateGeneratorEvaluationRequest, +): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/generators/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.create_generator_evaluation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + gcd_generator_evaluation.CreateGeneratorEvaluationRequest, + dict, + ], +) +def test_create_generator_evaluation_rest_call_success(request_type): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/generators/sample3"} + request_init["generator_evaluation"] = { + "name": "name_value", + "display_name": "display_name_value", + "generator_evaluation_config": { + "input_data_config": { + "input_data_source_type": 1, + "start_time": {"seconds": 751, "nanos": 543}, + "end_time": {}, + "sample_size": 1180, + "is_summary_generation_allowed": True, + "summary_generation_option": 1, + "agent_assist_input_data_config": {"start_time": {}, "end_time": {}}, + "dataset_input_data_config": {"dataset": "dataset_value"}, + }, + "output_gcs_bucket_path": "output_gcs_bucket_path_value", + "summarization_config": { + "enable_accuracy_evaluation": True, + "accuracy_evaluation_version": "accuracy_evaluation_version_value", + "enable_completeness_evaluation": True, + "completeness_evaluation_version": "completeness_evaluation_version_value", + "evaluator_version": "evaluator_version_value", + }, + }, + "create_time": {}, + "complete_time": {}, + "initial_generator": { + "name": "name_value", + "description": "description_value", + "free_form_context": {"text": "text_value"}, + "agent_coaching_context": { + "overarching_guidance": "overarching_guidance_value", + "instructions": [ + { + "display_name": "display_name_value", + "display_details": "display_details_value", + "condition": "condition_value", + "agent_action": "agent_action_value", + "system_action": "system_action_value", + "duplicate_check_result": { + "duplicate_suggestions": [ + { + "answer_record": "answer_record_value", + "suggestion_index": 1727, + "similarity_score": 0.17300000000000001, + } + ] + }, + } + ], + "version": "version_value", + "output_language_code": "output_language_code_value", + }, + "summarization_context": { + "summarization_sections": [ + {"key": "key_value", "definition": "definition_value", "type_": 1} + ], + "few_shot_examples": [ + { + "conversation_context": { + "message_entries": [ + { + "role": 1, + "text": "text_value", + "language_code": "language_code_value", + "create_time": {}, + } + ] + }, + "extra_info": {}, + "summarization_section_list": {"summarization_sections": {}}, + "output": { + "free_form_suggestion": {"response": "response_value"}, + "summary_suggestion": { + "summary_sections": [ + { + "section": "section_value", + "summary": "summary_value", + } + ] + }, + "agent_coaching_suggestion": { + "applicable_instructions": {}, + "agent_action_suggestions": [ + { + "agent_action": "agent_action_value", + "sources": { + "instruction_indexes": [2066, 2067] + }, + "duplicate_check_result": { + "duplicate_suggestions": [ + { + "answer_record": "answer_record_value", + "sources": {}, + "suggestion_index": 1727, + "similarity_score": 0.17300000000000001, + } + ] + }, + } + ], + "sample_responses": [ + { + "response_text": "response_text_value", + "sources": {}, + "duplicate_check_result": {}, + } + ], + }, + "tool_call_info": [ + { + "tool_call": { + "tool": "tool_value", + "tool_display_name": "tool_display_name_value", + "tool_display_details": "tool_display_details_value", + "action": "action_value", + "input_parameters": {"fields": {}}, + "create_time": {}, + "answer_record": "answer_record_value", + "state": 1, + }, + "tool_call_result": { + "tool": "tool_value", + "action": "action_value", + "error": {"message": "message_value"}, + "raw_content": b"raw_content_blob", + "content": "content_value", + "create_time": {}, + "answer_record": "answer_record_value", + }, + } + ], + }, + } + ], + "version": "version_value", + "output_language_code": "output_language_code_value", + }, + "inference_parameter": { + "max_output_tokens": 1865, + "temperature": 0.1198, + "top_k": 541, + "top_p": 0.546, + }, + "trigger_event": 1, + "published_model": "published_model_value", + "create_time": {}, + "update_time": {}, + "tools": ["tools_value1", "tools_value2"], + "suggestion_deduping_config": { + "enable_deduping": True, + "similarity_threshold": 0.21630000000000002, + }, + }, + "summarization_metrics": { + "summarization_evaluation_results": [ + { + "session_id": "session_id_value", + "metric": "metric_value", + "section": "section_value", + "score": 0.54, + "section_summary": "section_summary_value", + "decompositions": [ + { + "accuracy_decomposition": { + "point": "point_value", + "accuracy_reasoning": "accuracy_reasoning_value", + "is_accurate": True, + }, + "adherence_decomposition": { + "point": "point_value", + "adherence_reasoning": "adherence_reasoning_value", + "is_adherent": True, + }, + } + ], + "evaluation_results": [ + { + "accuracy_decomposition": {}, + "adherence_rubric": { + "question": "question_value", + "reasoning": "reasoning_value", + "is_addressed": True, + }, + "completeness_rubric": { + "question": "question_value", + "is_addressed": True, + }, + } + ], + } + ], + "summarization_evaluation_merged_results_uri": "summarization_evaluation_merged_results_uri_value", + "overall_metrics": [{"metric": "metric_value"}], + "overall_section_tokens": [ + {"section": "section_value", "token_count": 1193} + ], + "conversation_details": [ + { + "message_entries": {}, + "summary_sections": {}, + "metric_details": [ + { + "metric": "metric_value", + "score": 0.54, + "section_details": [ + { + "section": "section_value", + "score": 0.54, + "section_summary": "section_summary_value", + "evaluation_results": {}, + } + ], + } + ], + "section_tokens": {}, + } + ], + }, + "evaluation_status": { + "done": True, + "pipeline_status": { + "code": 411, + "message": "message_value", + "details": [ + { + "type_url": "type.googleapis.com/google.protobuf.Duration", + "value": b"\x08\x0c\x10\xdb\x07", + } + ], + }, + }, + "satisfies_pzs": True, + "satisfies_pzi": True, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = gcd_generator_evaluation.CreateGeneratorEvaluationRequest.meta.fields[ + "generator_evaluation" + ] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init[ + "generator_evaluation" + ].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["generator_evaluation"][field])): + del request_init["generator_evaluation"][field][i][subfield] + else: + del request_init["generator_evaluation"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.create_generator_evaluation(request) + + # Establish that the response is the type that we expect. + json_return_value = json_format.MessageToJson(return_value) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_generator_evaluation_rest_interceptors(null_interceptor): + transport = transports.GeneratorEvaluationsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.GeneratorEvaluationsRestInterceptor(), + ) + client = GeneratorEvaluationsClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.GeneratorEvaluationsRestInterceptor, + "post_create_generator_evaluation", + ) as post, mock.patch.object( + transports.GeneratorEvaluationsRestInterceptor, + "post_create_generator_evaluation_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.GeneratorEvaluationsRestInterceptor, + "pre_create_generator_evaluation", + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = gcd_generator_evaluation.CreateGeneratorEvaluationRequest.pb( + gcd_generator_evaluation.CreateGeneratorEvaluationRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = json_format.MessageToJson(operations_pb2.Operation()) + req.return_value.content = return_value + + request = gcd_generator_evaluation.CreateGeneratorEvaluationRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata + + client.create_generator_evaluation( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_generator_evaluation_rest_bad_request( + request_type=generator_evaluation.GetGeneratorEvaluationRequest, +): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/generators/sample3/evaluations/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_generator_evaluation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + generator_evaluation.GetGeneratorEvaluationRequest, + dict, + ], +) +def test_get_generator_evaluation_rest_call_success(request_type): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/generators/sample3/evaluations/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = generator_evaluation.GeneratorEvaluation( + name="name_value", + display_name="display_name_value", + satisfies_pzs=True, + satisfies_pzi=True, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = generator_evaluation.GeneratorEvaluation.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_generator_evaluation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, generator_evaluation.GeneratorEvaluation) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.satisfies_pzs is True + assert response.satisfies_pzi is True + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_generator_evaluation_rest_interceptors(null_interceptor): + transport = transports.GeneratorEvaluationsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.GeneratorEvaluationsRestInterceptor(), + ) + client = GeneratorEvaluationsClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.GeneratorEvaluationsRestInterceptor, "post_get_generator_evaluation" + ) as post, mock.patch.object( + transports.GeneratorEvaluationsRestInterceptor, + "post_get_generator_evaluation_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.GeneratorEvaluationsRestInterceptor, "pre_get_generator_evaluation" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = generator_evaluation.GetGeneratorEvaluationRequest.pb( + generator_evaluation.GetGeneratorEvaluationRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = generator_evaluation.GeneratorEvaluation.to_json( + generator_evaluation.GeneratorEvaluation() + ) + req.return_value.content = return_value + + request = generator_evaluation.GetGeneratorEvaluationRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = generator_evaluation.GeneratorEvaluation() + post_with_metadata.return_value = ( + generator_evaluation.GeneratorEvaluation(), + metadata, + ) + + client.get_generator_evaluation( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_generator_evaluations_rest_bad_request( + request_type=generator_evaluation.ListGeneratorEvaluationsRequest, +): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/generators/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_generator_evaluations(request) + + +@pytest.mark.parametrize( + "request_type", + [ + generator_evaluation.ListGeneratorEvaluationsRequest, + dict, + ], +) +def test_list_generator_evaluations_rest_call_success(request_type): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/generators/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = generator_evaluation.ListGeneratorEvaluationsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = generator_evaluation.ListGeneratorEvaluationsResponse.pb( + return_value + ) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_generator_evaluations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListGeneratorEvaluationsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_generator_evaluations_rest_interceptors(null_interceptor): + transport = transports.GeneratorEvaluationsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.GeneratorEvaluationsRestInterceptor(), + ) + client = GeneratorEvaluationsClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.GeneratorEvaluationsRestInterceptor, + "post_list_generator_evaluations", + ) as post, mock.patch.object( + transports.GeneratorEvaluationsRestInterceptor, + "post_list_generator_evaluations_with_metadata", + ) as post_with_metadata, mock.patch.object( + transports.GeneratorEvaluationsRestInterceptor, "pre_list_generator_evaluations" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = generator_evaluation.ListGeneratorEvaluationsRequest.pb( + generator_evaluation.ListGeneratorEvaluationsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = generator_evaluation.ListGeneratorEvaluationsResponse.to_json( + generator_evaluation.ListGeneratorEvaluationsResponse() + ) + req.return_value.content = return_value + + request = generator_evaluation.ListGeneratorEvaluationsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = generator_evaluation.ListGeneratorEvaluationsResponse() + post_with_metadata.return_value = ( + generator_evaluation.ListGeneratorEvaluationsResponse(), + metadata, + ) + + client.list_generator_evaluations( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_delete_generator_evaluation_rest_bad_request( + request_type=generator_evaluation.DeleteGeneratorEvaluationRequest, +): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/generators/sample3/evaluations/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.delete_generator_evaluation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + generator_evaluation.DeleteGeneratorEvaluationRequest, + dict, + ], +) +def test_delete_generator_evaluation_rest_call_success(request_type): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/locations/sample2/generators/sample3/evaluations/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = "" + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.delete_generator_evaluation(request) + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_generator_evaluation_rest_interceptors(null_interceptor): + transport = transports.GeneratorEvaluationsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.GeneratorEvaluationsRestInterceptor(), + ) + client = GeneratorEvaluationsClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.GeneratorEvaluationsRestInterceptor, + "pre_delete_generator_evaluation", + ) as pre: + pre.assert_not_called() + pb_message = generator_evaluation.DeleteGeneratorEvaluationRequest.pb( + generator_evaluation.DeleteGeneratorEvaluationRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + request = generator_evaluation.DeleteGeneratorEvaluationRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_generator_evaluation( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + + +def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "projects/sample1/locations/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_location(request) + + +@pytest.mark.parametrize( + "request_type", + [ + locations_pb2.GetLocationRequest, + dict, + ], +) +def test_get_location_rest(request_type): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = locations_pb2.Location() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_location(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.Location) + + +def test_list_locations_rest_bad_request( + request_type=locations_pb2.ListLocationsRequest, +): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict({"name": "projects/sample1"}, request) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_locations(request) + + +@pytest.mark.parametrize( + "request_type", + [ + locations_pb2.ListLocationsRequest, + dict, + ], +) +def test_list_locations_rest(request_type): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "projects/sample1"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = locations_pb2.ListLocationsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_locations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.ListLocationsResponse) + + +def test_cancel_operation_rest_bad_request( + request_type=operations_pb2.CancelOperationRequest, +): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "projects/sample1/operations/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.cancel_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.CancelOperationRequest, + dict, + ], +) +def test_cancel_operation_rest(request_type): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "projects/sample1/operations/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = "{}" + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.cancel_operation(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "projects/sample1/operations/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "projects/sample1/operations/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_list_operations_rest_bad_request( + request_type=operations_pb2.ListOperationsRequest, +): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict({"name": "projects/sample1"}, request) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_operations(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.ListOperationsRequest, + dict, + ], +) +def test_list_operations_rest(request_type): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "projects/sample1"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.ListOperationsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_initialize_client_w_rest(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_generator_evaluation_empty_call_rest(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.create_generator_evaluation), "__call__" + ) as call: + client.create_generator_evaluation(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcd_generator_evaluation.CreateGeneratorEvaluationRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_generator_evaluation_empty_call_rest(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.get_generator_evaluation), "__call__" + ) as call: + client.get_generator_evaluation(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = generator_evaluation.GetGeneratorEvaluationRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_generator_evaluations_empty_call_rest(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.list_generator_evaluations), "__call__" + ) as call: + client.list_generator_evaluations(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = generator_evaluation.ListGeneratorEvaluationsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_generator_evaluation_empty_call_rest(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object( + type(client.transport.delete_generator_evaluation), "__call__" + ) as call: + client.delete_generator_evaluation(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = generator_evaluation.DeleteGeneratorEvaluationRequest() + + assert args[0] == request_msg + + +def test_generator_evaluations_rest_lro_client(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + transport = client.transport + + # Ensure that we have an api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.AbstractOperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.GeneratorEvaluationsGrpcTransport, + ) + + +def test_generator_evaluations_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.GeneratorEvaluationsTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_generator_evaluations_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.cloud.dialogflow_v2beta1.services.generator_evaluations.transports.GeneratorEvaluationsTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.GeneratorEvaluationsTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "create_generator_evaluation", + "get_generator_evaluation", + "list_generator_evaluations", + "delete_generator_evaluation", + "get_location", + "list_locations", + "get_operation", + "cancel_operation", + "list_operations", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_generator_evaluations_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.cloud.dialogflow_v2beta1.services.generator_evaluations.transports.GeneratorEvaluationsTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.GeneratorEvaluationsTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=( + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/dialogflow", + ), + quota_project_id="octopus", + ) + + +def test_generator_evaluations_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.cloud.dialogflow_v2beta1.services.generator_evaluations.transports.GeneratorEvaluationsTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.GeneratorEvaluationsTransport() + adc.assert_called_once() + + +def test_generator_evaluations_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + GeneratorEvaluationsClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/dialogflow", + ), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.GeneratorEvaluationsGrpcTransport, + transports.GeneratorEvaluationsGrpcAsyncIOTransport, + ], +) +def test_generator_evaluations_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=( + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/dialogflow", + ), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.GeneratorEvaluationsGrpcTransport, + transports.GeneratorEvaluationsGrpcAsyncIOTransport, + transports.GeneratorEvaluationsRestTransport, + ], +) +def test_generator_evaluations_transport_auth_gdch_credentials(transport_class): + host = "https://language.com" + api_audience_tests = [None, "https://language2.com"] + api_audience_expect = [host, "https://language2.com"] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, "default", autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock( + return_value=gdch_mock + ) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with(e) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.GeneratorEvaluationsGrpcTransport, grpc_helpers), + (transports.GeneratorEvaluationsGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +def test_generator_evaluations_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "dialogflow.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/dialogflow", + ), + scopes=["1", "2"], + default_host="dialogflow.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.GeneratorEvaluationsGrpcTransport, + transports.GeneratorEvaluationsGrpcAsyncIOTransport, + ], +) +def test_generator_evaluations_grpc_transport_client_cert_source_for_mtls( + transport_class, +): + cred = ga_credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds, + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback, + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, private_key=expected_key + ) + + +def test_generator_evaluations_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.GeneratorEvaluationsRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_generator_evaluations_host_no_port(transport_name): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="dialogflow.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "dialogflow.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://dialogflow.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_generator_evaluations_host_with_port(transport_name): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="dialogflow.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "dialogflow.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://dialogflow.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_generator_evaluations_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = GeneratorEvaluationsClient( + credentials=creds1, + transport=transport_name, + ) + client2 = GeneratorEvaluationsClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.create_generator_evaluation._session + session2 = client2.transport.create_generator_evaluation._session + assert session1 != session2 + session1 = client1.transport.get_generator_evaluation._session + session2 = client2.transport.get_generator_evaluation._session + assert session1 != session2 + session1 = client1.transport.list_generator_evaluations._session + session2 = client2.transport.list_generator_evaluations._session + assert session1 != session2 + session1 = client1.transport.delete_generator_evaluation._session + session2 = client2.transport.delete_generator_evaluation._session + assert session1 != session2 + + +def test_generator_evaluations_grpc_transport_channel(): + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.GeneratorEvaluationsGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_generator_evaluations_grpc_asyncio_transport_channel(): + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.GeneratorEvaluationsGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize( + "transport_class", + [ + transports.GeneratorEvaluationsGrpcTransport, + transports.GeneratorEvaluationsGrpcAsyncIOTransport, + ], +) +def test_generator_evaluations_transport_channel_mtls_with_client_cert_source( + transport_class, +): + with mock.patch( + "grpc.ssl_channel_credentials", autospec=True + ) as grpc_ssl_channel_cred: + with mock.patch.object( + transport_class, "create_channel" + ) as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize( + "transport_class", + [ + transports.GeneratorEvaluationsGrpcTransport, + transports.GeneratorEvaluationsGrpcAsyncIOTransport, + ], +) +def test_generator_evaluations_transport_channel_mtls_with_adc(transport_class): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object( + transport_class, "create_channel" + ) as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_generator_evaluations_grpc_lro_client(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_generator_evaluations_grpc_lro_async_client(): + client = GeneratorEvaluationsAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsAsyncClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_generator_path(): + project = "squid" + location = "clam" + generator = "whelk" + expected = "projects/{project}/locations/{location}/generators/{generator}".format( + project=project, + location=location, + generator=generator, + ) + actual = GeneratorEvaluationsClient.generator_path(project, location, generator) + assert expected == actual + + +def test_parse_generator_path(): + expected = { + "project": "octopus", + "location": "oyster", + "generator": "nudibranch", + } + path = GeneratorEvaluationsClient.generator_path(**expected) + + # Check that the path construction is reversible. + actual = GeneratorEvaluationsClient.parse_generator_path(path) + assert expected == actual + + +def test_generator_evaluation_path(): + project = "cuttlefish" + location = "mussel" + generator = "winkle" + evaluation = "nautilus" + expected = "projects/{project}/locations/{location}/generators/{generator}/evaluations/{evaluation}".format( + project=project, + location=location, + generator=generator, + evaluation=evaluation, + ) + actual = GeneratorEvaluationsClient.generator_evaluation_path( + project, location, generator, evaluation + ) + assert expected == actual + + +def test_parse_generator_evaluation_path(): + expected = { + "project": "scallop", + "location": "abalone", + "generator": "squid", + "evaluation": "clam", + } + path = GeneratorEvaluationsClient.generator_evaluation_path(**expected) + + # Check that the path construction is reversible. + actual = GeneratorEvaluationsClient.parse_generator_evaluation_path(path) + assert expected == actual + + +def test_tool_path(): + project = "whelk" + location = "octopus" + tool = "oyster" + expected = "projects/{project}/locations/{location}/tools/{tool}".format( + project=project, + location=location, + tool=tool, + ) + actual = GeneratorEvaluationsClient.tool_path(project, location, tool) + assert expected == actual + + +def test_parse_tool_path(): + expected = { + "project": "nudibranch", + "location": "cuttlefish", + "tool": "mussel", + } + path = GeneratorEvaluationsClient.tool_path(**expected) + + # Check that the path construction is reversible. + actual = GeneratorEvaluationsClient.parse_tool_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "winkle" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = GeneratorEvaluationsClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "nautilus", + } + path = GeneratorEvaluationsClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = GeneratorEvaluationsClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "scallop" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = GeneratorEvaluationsClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "abalone", + } + path = GeneratorEvaluationsClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = GeneratorEvaluationsClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "squid" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = GeneratorEvaluationsClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "clam", + } + path = GeneratorEvaluationsClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = GeneratorEvaluationsClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "whelk" + expected = "projects/{project}".format( + project=project, + ) + actual = GeneratorEvaluationsClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "octopus", + } + path = GeneratorEvaluationsClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = GeneratorEvaluationsClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "oyster" + location = "nudibranch" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = GeneratorEvaluationsClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "cuttlefish", + "location": "mussel", + } + path = GeneratorEvaluationsClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = GeneratorEvaluationsClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object( + transports.GeneratorEvaluationsTransport, "_prep_wrapped_messages" + ) as prep: + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object( + transports.GeneratorEvaluationsTransport, "_prep_wrapped_messages" + ) as prep: + transport_class = GeneratorEvaluationsClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_cancel_operation(transport: str = "grpc"): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.CancelOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_cancel_operation_async(transport: str = "grpc_asyncio"): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.CancelOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +def test_cancel_operation_field_headers(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.CancelOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + call.return_value = None + + client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_cancel_operation_field_headers_async(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.CancelOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_cancel_operation_from_dict(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + + response = client.cancel_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_cancel_operation_from_dict_async(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.cancel_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_get_operation(transport: str = "grpc"): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc_asyncio"): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_get_operation_field_headers(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_get_operation_from_dict(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc_asyncio"): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_list_operations_field_headers(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_list_operations_from_dict(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_locations(transport: str = "grpc"): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = locations_pb2.ListLocationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.ListLocationsResponse() + response = client.list_locations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.ListLocationsResponse) + + +@pytest.mark.asyncio +async def test_list_locations_async(transport: str = "grpc_asyncio"): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = locations_pb2.ListLocationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + response = await client.list_locations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.ListLocationsResponse) + + +def test_list_locations_field_headers(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = locations_pb2.ListLocationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + call.return_value = locations_pb2.ListLocationsResponse() + + client.list_locations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_locations_field_headers_async(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = locations_pb2.ListLocationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + await client.list_locations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_list_locations_from_dict(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.ListLocationsResponse() + + response = client.list_locations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_list_locations_from_dict_async(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + response = await client.list_locations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_get_location(transport: str = "grpc"): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = locations_pb2.GetLocationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.Location() + response = client.get_location(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.Location) + + +@pytest.mark.asyncio +async def test_get_location_async(transport: str = "grpc_asyncio"): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = locations_pb2.GetLocationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + response = await client.get_location(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.Location) + + +def test_get_location_field_headers(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials() + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = locations_pb2.GetLocationRequest() + request.name = "locations/abc" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + call.return_value = locations_pb2.Location() + + client.get_location(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations/abc", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_location_field_headers_async(): + client = GeneratorEvaluationsAsyncClient(credentials=async_anonymous_credentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = locations_pb2.GetLocationRequest() + request.name = "locations/abc" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + await client.get_location(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations/abc", + ) in kw["metadata"] + + +def test_get_location_from_dict(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.Location() + + response = client.get_location( + request={ + "name": "locations/abc", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_get_location_from_dict_async(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + response = await client.get_location( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close_grpc(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +@pytest.mark.asyncio +async def test_transport_close_grpc_asyncio(): + client = GeneratorEvaluationsAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close_rest(): + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + "grpc", + ] + for transport in transports: + client = GeneratorEvaluationsClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (GeneratorEvaluationsClient, transports.GeneratorEvaluationsGrpcTransport), + ( + GeneratorEvaluationsAsyncClient, + transports.GeneratorEvaluationsGrpcAsyncIOTransport, + ), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_generators.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_generators.py index a7ef53b6378f..778b36751936 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_generators.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_generators.py @@ -54,6 +54,7 @@ from google.longrunning import operations_pb2 # type: ignore from google.oauth2 import service_account from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import struct_pb2 # type: ignore from google.protobuf import timestamp_pb2 # type: ignore from google.cloud.dialogflow_v2beta1.services.generators import ( @@ -62,8 +63,10 @@ pagers, transports, ) +from google.cloud.dialogflow_v2beta1.types import agent_coaching_instruction from google.cloud.dialogflow_v2beta1.types import generator from google.cloud.dialogflow_v2beta1.types import generator as gcd_generator +from google.cloud.dialogflow_v2beta1.types import tool_call CRED_INFO_JSON = { "credential_source": "/path/to/file", @@ -1101,6 +1104,7 @@ def test_create_generator(request_type, transport: str = "grpc"): name="name_value", description="description_value", trigger_event=gcd_generator.TriggerEvent.END_OF_UTTERANCE, + tools=["tools_value"], published_model="published_model_value", ) response = client.create_generator(request) @@ -1116,6 +1120,7 @@ def test_create_generator(request_type, transport: str = "grpc"): assert response.name == "name_value" assert response.description == "description_value" assert response.trigger_event == gcd_generator.TriggerEvent.END_OF_UTTERANCE + assert response.tools == ["tools_value"] def test_create_generator_non_empty_request_with_auto_populated_field(): @@ -1248,6 +1253,7 @@ async def test_create_generator_async( name="name_value", description="description_value", trigger_event=gcd_generator.TriggerEvent.END_OF_UTTERANCE, + tools=["tools_value"], ) ) response = await client.create_generator(request) @@ -1263,6 +1269,7 @@ async def test_create_generator_async( assert response.name == "name_value" assert response.description == "description_value" assert response.trigger_event == gcd_generator.TriggerEvent.END_OF_UTTERANCE + assert response.tools == ["tools_value"] @pytest.mark.asyncio @@ -1457,6 +1464,7 @@ def test_get_generator(request_type, transport: str = "grpc"): name="name_value", description="description_value", trigger_event=generator.TriggerEvent.END_OF_UTTERANCE, + tools=["tools_value"], published_model="published_model_value", ) response = client.get_generator(request) @@ -1472,6 +1480,7 @@ def test_get_generator(request_type, transport: str = "grpc"): assert response.name == "name_value" assert response.description == "description_value" assert response.trigger_event == generator.TriggerEvent.END_OF_UTTERANCE + assert response.tools == ["tools_value"] def test_get_generator_non_empty_request_with_auto_populated_field(): @@ -1600,6 +1609,7 @@ async def test_get_generator_async( name="name_value", description="description_value", trigger_event=generator.TriggerEvent.END_OF_UTTERANCE, + tools=["tools_value"], ) ) response = await client.get_generator(request) @@ -1615,6 +1625,7 @@ async def test_get_generator_async( assert response.name == "name_value" assert response.description == "description_value" assert response.trigger_event == generator.TriggerEvent.END_OF_UTTERANCE + assert response.tools == ["tools_value"] @pytest.mark.asyncio @@ -2617,6 +2628,7 @@ def test_update_generator(request_type, transport: str = "grpc"): name="name_value", description="description_value", trigger_event=gcd_generator.TriggerEvent.END_OF_UTTERANCE, + tools=["tools_value"], published_model="published_model_value", ) response = client.update_generator(request) @@ -2632,6 +2644,7 @@ def test_update_generator(request_type, transport: str = "grpc"): assert response.name == "name_value" assert response.description == "description_value" assert response.trigger_event == gcd_generator.TriggerEvent.END_OF_UTTERANCE + assert response.tools == ["tools_value"] def test_update_generator_non_empty_request_with_auto_populated_field(): @@ -2758,6 +2771,7 @@ async def test_update_generator_async( name="name_value", description="description_value", trigger_event=gcd_generator.TriggerEvent.END_OF_UTTERANCE, + tools=["tools_value"], ) ) response = await client.update_generator(request) @@ -2773,6 +2787,7 @@ async def test_update_generator_async( assert response.name == "name_value" assert response.description == "description_value" assert response.trigger_event == gcd_generator.TriggerEvent.END_OF_UTTERANCE + assert response.tools == ["tools_value"] @pytest.mark.asyncio @@ -4163,6 +4178,7 @@ async def test_create_generator_empty_call_grpc_asyncio(): name="name_value", description="description_value", trigger_event=gcd_generator.TriggerEvent.END_OF_UTTERANCE, + tools=["tools_value"], ) ) await client.create_generator(request=None) @@ -4192,6 +4208,7 @@ async def test_get_generator_empty_call_grpc_asyncio(): name="name_value", description="description_value", trigger_event=generator.TriggerEvent.END_OF_UTTERANCE, + tools=["tools_value"], ) ) await client.get_generator(request=None) @@ -4271,6 +4288,7 @@ async def test_update_generator_empty_call_grpc_asyncio(): name="name_value", description="description_value", trigger_event=gcd_generator.TriggerEvent.END_OF_UTTERANCE, + tools=["tools_value"], ) ) await client.update_generator(request=None) @@ -4333,6 +4351,29 @@ def test_create_generator_rest_call_success(request_type): "name": "name_value", "description": "description_value", "free_form_context": {"text": "text_value"}, + "agent_coaching_context": { + "overarching_guidance": "overarching_guidance_value", + "instructions": [ + { + "display_name": "display_name_value", + "display_details": "display_details_value", + "condition": "condition_value", + "agent_action": "agent_action_value", + "system_action": "system_action_value", + "duplicate_check_result": { + "duplicate_suggestions": [ + { + "answer_record": "answer_record_value", + "suggestion_index": 1727, + "similarity_score": 0.17300000000000001, + } + ] + }, + } + ], + "version": "version_value", + "output_language_code": "output_language_code_value", + }, "summarization_context": { "summarization_sections": [ {"key": "key_value", "definition": "definition_value", "type_": 1} @@ -4358,6 +4399,55 @@ def test_create_generator_rest_call_success(request_type): {"section": "section_value", "summary": "summary_value"} ] }, + "agent_coaching_suggestion": { + "applicable_instructions": {}, + "agent_action_suggestions": [ + { + "agent_action": "agent_action_value", + "sources": {"instruction_indexes": [2066, 2067]}, + "duplicate_check_result": { + "duplicate_suggestions": [ + { + "answer_record": "answer_record_value", + "sources": {}, + "suggestion_index": 1727, + "similarity_score": 0.17300000000000001, + } + ] + }, + } + ], + "sample_responses": [ + { + "response_text": "response_text_value", + "sources": {}, + "duplicate_check_result": {}, + } + ], + }, + "tool_call_info": [ + { + "tool_call": { + "tool": "tool_value", + "tool_display_name": "tool_display_name_value", + "tool_display_details": "tool_display_details_value", + "action": "action_value", + "input_parameters": {"fields": {}}, + "create_time": {}, + "answer_record": "answer_record_value", + "state": 1, + }, + "tool_call_result": { + "tool": "tool_value", + "action": "action_value", + "error": {"message": "message_value"}, + "raw_content": b"raw_content_blob", + "content": "content_value", + "create_time": {}, + "answer_record": "answer_record_value", + }, + } + ], }, } ], @@ -4374,6 +4464,11 @@ def test_create_generator_rest_call_success(request_type): "published_model": "published_model_value", "create_time": {}, "update_time": {}, + "tools": ["tools_value1", "tools_value2"], + "suggestion_deduping_config": { + "enable_deduping": True, + "similarity_threshold": 0.21630000000000002, + }, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -4451,6 +4546,7 @@ def get_message_fields(field): name="name_value", description="description_value", trigger_event=gcd_generator.TriggerEvent.END_OF_UTTERANCE, + tools=["tools_value"], published_model="published_model_value", ) @@ -4471,6 +4567,7 @@ def get_message_fields(field): assert response.name == "name_value" assert response.description == "description_value" assert response.trigger_event == gcd_generator.TriggerEvent.END_OF_UTTERANCE + assert response.tools == ["tools_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -4581,6 +4678,7 @@ def test_get_generator_rest_call_success(request_type): name="name_value", description="description_value", trigger_event=generator.TriggerEvent.END_OF_UTTERANCE, + tools=["tools_value"], published_model="published_model_value", ) @@ -4601,6 +4699,7 @@ def test_get_generator_rest_call_success(request_type): assert response.name == "name_value" assert response.description == "description_value" assert response.trigger_event == generator.TriggerEvent.END_OF_UTTERANCE + assert response.tools == ["tools_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -4946,6 +5045,29 @@ def test_update_generator_rest_call_success(request_type): "name": "projects/sample1/locations/sample2/generators/sample3", "description": "description_value", "free_form_context": {"text": "text_value"}, + "agent_coaching_context": { + "overarching_guidance": "overarching_guidance_value", + "instructions": [ + { + "display_name": "display_name_value", + "display_details": "display_details_value", + "condition": "condition_value", + "agent_action": "agent_action_value", + "system_action": "system_action_value", + "duplicate_check_result": { + "duplicate_suggestions": [ + { + "answer_record": "answer_record_value", + "suggestion_index": 1727, + "similarity_score": 0.17300000000000001, + } + ] + }, + } + ], + "version": "version_value", + "output_language_code": "output_language_code_value", + }, "summarization_context": { "summarization_sections": [ {"key": "key_value", "definition": "definition_value", "type_": 1} @@ -4971,6 +5093,55 @@ def test_update_generator_rest_call_success(request_type): {"section": "section_value", "summary": "summary_value"} ] }, + "agent_coaching_suggestion": { + "applicable_instructions": {}, + "agent_action_suggestions": [ + { + "agent_action": "agent_action_value", + "sources": {"instruction_indexes": [2066, 2067]}, + "duplicate_check_result": { + "duplicate_suggestions": [ + { + "answer_record": "answer_record_value", + "sources": {}, + "suggestion_index": 1727, + "similarity_score": 0.17300000000000001, + } + ] + }, + } + ], + "sample_responses": [ + { + "response_text": "response_text_value", + "sources": {}, + "duplicate_check_result": {}, + } + ], + }, + "tool_call_info": [ + { + "tool_call": { + "tool": "tool_value", + "tool_display_name": "tool_display_name_value", + "tool_display_details": "tool_display_details_value", + "action": "action_value", + "input_parameters": {"fields": {}}, + "create_time": {}, + "answer_record": "answer_record_value", + "state": 1, + }, + "tool_call_result": { + "tool": "tool_value", + "action": "action_value", + "error": {"message": "message_value"}, + "raw_content": b"raw_content_blob", + "content": "content_value", + "create_time": {}, + "answer_record": "answer_record_value", + }, + } + ], }, } ], @@ -4987,6 +5158,11 @@ def test_update_generator_rest_call_success(request_type): "published_model": "published_model_value", "create_time": {}, "update_time": {}, + "tools": ["tools_value1", "tools_value2"], + "suggestion_deduping_config": { + "enable_deduping": True, + "similarity_threshold": 0.21630000000000002, + }, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency @@ -5064,6 +5240,7 @@ def get_message_fields(field): name="name_value", description="description_value", trigger_event=gcd_generator.TriggerEvent.END_OF_UTTERANCE, + tools=["tools_value"], published_model="published_model_value", ) @@ -5084,6 +5261,7 @@ def get_message_fields(field): assert response.name == "name_value" assert response.description == "description_value" assert response.trigger_event == gcd_generator.TriggerEvent.END_OF_UTTERANCE + assert response.tools == ["tools_value"] @pytest.mark.parametrize("null_interceptor", [True, False]) @@ -6030,8 +6208,34 @@ def test_parse_generator_path(): assert expected == actual +def test_tool_path(): + project = "cuttlefish" + location = "mussel" + tool = "winkle" + expected = "projects/{project}/locations/{location}/tools/{tool}".format( + project=project, + location=location, + tool=tool, + ) + actual = GeneratorsClient.tool_path(project, location, tool) + assert expected == actual + + +def test_parse_tool_path(): + expected = { + "project": "nautilus", + "location": "scallop", + "tool": "abalone", + } + path = GeneratorsClient.tool_path(**expected) + + # Check that the path construction is reversible. + actual = GeneratorsClient.parse_tool_path(path) + assert expected == actual + + def test_common_billing_account_path(): - billing_account = "cuttlefish" + billing_account = "squid" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -6041,7 +6245,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "mussel", + "billing_account": "clam", } path = GeneratorsClient.common_billing_account_path(**expected) @@ -6051,7 +6255,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "winkle" + folder = "whelk" expected = "folders/{folder}".format( folder=folder, ) @@ -6061,7 +6265,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "nautilus", + "folder": "octopus", } path = GeneratorsClient.common_folder_path(**expected) @@ -6071,7 +6275,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "scallop" + organization = "oyster" expected = "organizations/{organization}".format( organization=organization, ) @@ -6081,7 +6285,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "abalone", + "organization": "nudibranch", } path = GeneratorsClient.common_organization_path(**expected) @@ -6091,7 +6295,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "squid" + project = "cuttlefish" expected = "projects/{project}".format( project=project, ) @@ -6101,7 +6305,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "clam", + "project": "mussel", } path = GeneratorsClient.common_project_path(**expected) @@ -6111,8 +6315,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "whelk" - location = "octopus" + project = "winkle" + location = "nautilus" expected = "projects/{project}/locations/{location}".format( project=project, location=location, @@ -6123,8 +6327,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "oyster", - "location": "nudibranch", + "project": "scallop", + "location": "abalone", } path = GeneratorsClient.common_location_path(**expected) diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_participants.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_participants.py index ca1c575c202c..3a94f56ef64d 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_participants.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_participants.py @@ -3211,6 +3211,165 @@ async def test_streaming_analyze_content_async_from_dict(): await test_streaming_analyze_content_async(request_type=dict) +@pytest.mark.parametrize( + "request_type", + [ + participant.BidiStreamingAnalyzeContentRequest, + dict, + ], +) +def test_bidi_streaming_analyze_content(request_type, transport: str = "grpc"): + client = ParticipantsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + requests = [request] + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.bidi_streaming_analyze_content), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = iter([participant.BidiStreamingAnalyzeContentResponse()]) + response = client.bidi_streaming_analyze_content(iter(requests)) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert next(args[0]) == request + + # Establish that the response is the type that we expect. + for message in response: + assert isinstance(message, participant.BidiStreamingAnalyzeContentResponse) + + +def test_bidi_streaming_analyze_content_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ParticipantsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._transport.bidi_streaming_analyze_content + in client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[ + client._transport.bidi_streaming_analyze_content + ] = mock_rpc + request = [{}] + client.bidi_streaming_analyze_content(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.bidi_streaming_analyze_content(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_bidi_streaming_analyze_content_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = ParticipantsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.bidi_streaming_analyze_content + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.bidi_streaming_analyze_content + ] = mock_rpc + + request = [{}] + await client.bidi_streaming_analyze_content(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.bidi_streaming_analyze_content(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_bidi_streaming_analyze_content_async( + transport: str = "grpc_asyncio", + request_type=participant.BidiStreamingAnalyzeContentRequest, +): + client = ParticipantsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + requests = [request] + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.bidi_streaming_analyze_content), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = mock.Mock(aio.StreamStreamCall, autospec=True) + call.return_value.read = mock.AsyncMock( + side_effect=[participant.BidiStreamingAnalyzeContentResponse()] + ) + response = await client.bidi_streaming_analyze_content(iter(requests)) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert next(args[0]) == request + + # Establish that the response is the type that we expect. + message = await response.read() + assert isinstance(message, participant.BidiStreamingAnalyzeContentResponse) + + +@pytest.mark.asyncio +async def test_bidi_streaming_analyze_content_async_from_dict(): + await test_bidi_streaming_analyze_content_async(request_type=dict) + + @pytest.mark.parametrize( "request_type", [ @@ -6228,6 +6387,17 @@ def test_streaming_analyze_content_rest_no_http_options(): client.streaming_analyze_content(requests) +def test_bidi_streaming_analyze_content_rest_no_http_options(): + client = ParticipantsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = participant.BidiStreamingAnalyzeContentRequest() + requests = [request] + with pytest.raises(RuntimeError): + client.bidi_streaming_analyze_content(requests) + + def test_suggest_articles_rest_use_cached_wrapped_rpc(): # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, # instead of constructing them on each call @@ -7064,6 +7234,20 @@ def test_streaming_analyze_content_rest_error(): ) +def test_bidi_streaming_analyze_content_rest_error(): + client = ParticipantsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # Since a `google.api.http` annotation is required for using a rest transport + # method, this should error. + with pytest.raises(NotImplementedError) as not_implemented_error: + client.bidi_streaming_analyze_content({}) + assert ( + "Method BidiStreamingAnalyzeContent is not available over REST transport" + in str(not_implemented_error.value) + ) + + def test_credentials_transport_error(): # It is an error to provide credentials and a transport instance. transport = transports.ParticipantsGrpcTransport( @@ -8593,6 +8777,19 @@ def test_streaming_analyze_content_rest_error(): ) +def test_bidi_streaming_analyze_content_rest_error(): + client = ParticipantsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + with pytest.raises(NotImplementedError) as not_implemented_error: + client.bidi_streaming_analyze_content({}) + assert ( + "Method BidiStreamingAnalyzeContent is not available over REST transport" + in str(not_implemented_error.value) + ) + + def test_suggest_articles_rest_bad_request( request_type=participant.SuggestArticlesRequest, ): @@ -10005,6 +10202,7 @@ def test_participants_base_transport(): "update_participant", "analyze_content", "streaming_analyze_content", + "bidi_streaming_analyze_content", "suggest_articles", "suggest_faq_answers", "suggest_smart_replies", @@ -10301,6 +10499,9 @@ def test_participants_client_transport_session_collision(transport_name): session1 = client1.transport.streaming_analyze_content._session session2 = client2.transport.streaming_analyze_content._session assert session1 != session2 + session1 = client1.transport.bidi_streaming_analyze_content._session + session2 = client2.transport.bidi_streaming_analyze_content._session + assert session1 != session2 session1 = client1.transport.suggest_articles._session session2 = client2.transport.suggest_articles._session assert session1 != session2 @@ -10645,8 +10846,34 @@ def test_parse_session_entity_type_path(): assert expected == actual +def test_tool_path(): + project = "winkle" + location = "nautilus" + tool = "scallop" + expected = "projects/{project}/locations/{location}/tools/{tool}".format( + project=project, + location=location, + tool=tool, + ) + actual = ParticipantsClient.tool_path(project, location, tool) + assert expected == actual + + +def test_parse_tool_path(): + expected = { + "project": "abalone", + "location": "squid", + "tool": "clam", + } + path = ParticipantsClient.tool_path(**expected) + + # Check that the path construction is reversible. + actual = ParticipantsClient.parse_tool_path(path) + assert expected == actual + + def test_common_billing_account_path(): - billing_account = "winkle" + billing_account = "whelk" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -10656,7 +10883,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "nautilus", + "billing_account": "octopus", } path = ParticipantsClient.common_billing_account_path(**expected) @@ -10666,7 +10893,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "scallop" + folder = "oyster" expected = "folders/{folder}".format( folder=folder, ) @@ -10676,7 +10903,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "abalone", + "folder": "nudibranch", } path = ParticipantsClient.common_folder_path(**expected) @@ -10686,7 +10913,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "squid" + organization = "cuttlefish" expected = "organizations/{organization}".format( organization=organization, ) @@ -10696,7 +10923,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "clam", + "organization": "mussel", } path = ParticipantsClient.common_organization_path(**expected) @@ -10706,7 +10933,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "whelk" + project = "winkle" expected = "projects/{project}".format( project=project, ) @@ -10716,7 +10943,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "octopus", + "project": "nautilus", } path = ParticipantsClient.common_project_path(**expected) @@ -10726,8 +10953,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "oyster" - location = "nudibranch" + project = "scallop" + location = "abalone" expected = "projects/{project}/locations/{location}".format( project=project, location=location, @@ -10738,8 +10965,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "cuttlefish", - "location": "mussel", + "project": "squid", + "location": "clam", } path = ParticipantsClient.common_location_path(**expected) diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_tools.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_tools.py new file mode 100644 index 000000000000..f80ad507efa2 --- /dev/null +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_tools.py @@ -0,0 +1,6998 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +# try/except added for compatibility with python < 3.8 +try: + from unittest import mock + from unittest.mock import AsyncMock # pragma: NO COVER +except ImportError: # pragma: NO COVER + import mock + +from collections.abc import AsyncIterable, Iterable +import json +import math + +from google.api_core import api_core_version +from google.protobuf import json_format +import grpc +from grpc.experimental import aio +from proto.marshal.rules import wrappers +from proto.marshal.rules.dates import DurationRule, TimestampRule +import pytest +from requests import PreparedRequest, Request, Response +from requests.sessions import Session + +try: + from google.auth.aio import credentials as ga_credentials_async + + HAS_GOOGLE_AUTH_AIO = True +except ImportError: # pragma: NO COVER + HAS_GOOGLE_AUTH_AIO = False + +from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import client_options +from google.api_core import exceptions as core_exceptions +from google.api_core import retry as retries +import google.auth +from google.auth import credentials as ga_credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.location import locations_pb2 +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import struct_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + +from google.cloud.dialogflow_v2beta1.services.tools import ( + ToolsAsyncClient, + ToolsClient, + pagers, + transports, +) +from google.cloud.dialogflow_v2beta1.types import tool +from google.cloud.dialogflow_v2beta1.types import tool as gcd_tool + +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + + +async def mock_async_gen(data, chunk_size=1): + for i in range(0, len(data)): # pragma: NO COVER + chunk = data[i : i + chunk_size] + yield chunk.encode("utf-8") + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +# TODO: use async auth anon credentials by default once the minimum version of google-auth is upgraded. +# See related issue: https://github.com/googleapis/gapic-generator-python/issues/2107. +def async_anonymous_credentials(): + if HAS_GOOGLE_AUTH_AIO: + return ga_credentials_async.AnonymousCredentials() + return ga_credentials.AnonymousCredentials() + + +# If default endpoint is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint(client): + return ( + "foo.googleapis.com" + if ("localhost" in client.DEFAULT_ENDPOINT) + else client.DEFAULT_ENDPOINT + ) + + +# If default endpoint template is localhost, then default mtls endpoint will be the same. +# This method modifies the default endpoint template so the client can produce a different +# mtls endpoint for endpoint testing purposes. +def modify_default_endpoint_template(client): + return ( + "test.{UNIVERSE_DOMAIN}" + if ("localhost" in client._DEFAULT_ENDPOINT_TEMPLATE) + else client._DEFAULT_ENDPOINT_TEMPLATE + ) + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert ToolsClient._get_default_mtls_endpoint(None) is None + assert ToolsClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ( + ToolsClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + ) + assert ( + ToolsClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + ToolsClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ToolsClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +def test__read_environment_variables(): + assert ToolsClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + assert ToolsClient._read_environment_variables() == (True, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + assert ToolsClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + ToolsClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + assert ToolsClient._read_environment_variables() == (False, "never", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + assert ToolsClient._read_environment_variables() == (False, "always", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}): + assert ToolsClient._read_environment_variables() == (False, "auto", None) + + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + ToolsClient._read_environment_variables() + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + with mock.patch.dict(os.environ, {"GOOGLE_CLOUD_UNIVERSE_DOMAIN": "foo.com"}): + assert ToolsClient._read_environment_variables() == (False, "auto", "foo.com") + + +def test__get_client_cert_source(): + mock_provided_cert_source = mock.Mock() + mock_default_cert_source = mock.Mock() + + assert ToolsClient._get_client_cert_source(None, False) is None + assert ToolsClient._get_client_cert_source(mock_provided_cert_source, False) is None + assert ( + ToolsClient._get_client_cert_source(mock_provided_cert_source, True) + == mock_provided_cert_source + ) + + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", return_value=True + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_default_cert_source, + ): + assert ( + ToolsClient._get_client_cert_source(None, True) + is mock_default_cert_source + ) + assert ( + ToolsClient._get_client_cert_source(mock_provided_cert_source, "true") + is mock_provided_cert_source + ) + + +@mock.patch.object( + ToolsClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ToolsClient), +) +@mock.patch.object( + ToolsAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ToolsAsyncClient), +) +def test__get_api_endpoint(): + api_override = "foo.com" + mock_client_cert_source = mock.Mock() + default_universe = ToolsClient._DEFAULT_UNIVERSE + default_endpoint = ToolsClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = ToolsClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + assert ( + ToolsClient._get_api_endpoint( + api_override, mock_client_cert_source, default_universe, "always" + ) + == api_override + ) + assert ( + ToolsClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "auto" + ) + == ToolsClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + ToolsClient._get_api_endpoint(None, None, default_universe, "auto") + == default_endpoint + ) + assert ( + ToolsClient._get_api_endpoint(None, None, default_universe, "always") + == ToolsClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + ToolsClient._get_api_endpoint( + None, mock_client_cert_source, default_universe, "always" + ) + == ToolsClient.DEFAULT_MTLS_ENDPOINT + ) + assert ( + ToolsClient._get_api_endpoint(None, None, mock_universe, "never") + == mock_endpoint + ) + assert ( + ToolsClient._get_api_endpoint(None, None, default_universe, "never") + == default_endpoint + ) + + with pytest.raises(MutualTLSChannelError) as excinfo: + ToolsClient._get_api_endpoint( + None, mock_client_cert_source, mock_universe, "auto" + ) + assert ( + str(excinfo.value) + == "mTLS is not supported in any universe other than googleapis.com." + ) + + +def test__get_universe_domain(): + client_universe_domain = "foo.com" + universe_domain_env = "bar.com" + + assert ( + ToolsClient._get_universe_domain(client_universe_domain, universe_domain_env) + == client_universe_domain + ) + assert ( + ToolsClient._get_universe_domain(None, universe_domain_env) + == universe_domain_env + ) + assert ToolsClient._get_universe_domain(None, None) == ToolsClient._DEFAULT_UNIVERSE + + with pytest.raises(ValueError) as excinfo: + ToolsClient._get_universe_domain("", None) + assert str(excinfo.value) == "Universe Domain cannot be an empty string." + + +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ToolsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ToolsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (ToolsClient, "grpc"), + (ToolsAsyncClient, "grpc_asyncio"), + (ToolsClient, "rest"), + ], +) +def test_tools_client_from_service_account_info(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_info" + ) as factory: + factory.return_value = creds + info = {"valid": True} + client = client_class.from_service_account_info(info, transport=transport_name) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "dialogflow.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://dialogflow.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_class,transport_name", + [ + (transports.ToolsGrpcTransport, "grpc"), + (transports.ToolsGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ToolsRestTransport, "rest"), + ], +) +def test_tools_client_service_account_always_use_jwt(transport_class, transport_name): + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=True) + use_jwt.assert_called_once_with(True) + + with mock.patch.object( + service_account.Credentials, "with_always_use_jwt_access", create=True + ) as use_jwt: + creds = service_account.Credentials(None, None, None) + transport = transport_class(credentials=creds, always_use_jwt_access=False) + use_jwt.assert_not_called() + + +@pytest.mark.parametrize( + "client_class,transport_name", + [ + (ToolsClient, "grpc"), + (ToolsAsyncClient, "grpc_asyncio"), + (ToolsClient, "rest"), + ], +) +def test_tools_client_from_service_account_file(client_class, transport_name): + creds = ga_credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + client = client_class.from_service_account_json( + "dummy/file/path.json", transport=transport_name + ) + assert client.transport._credentials == creds + assert isinstance(client, client_class) + + assert client.transport._host == ( + "dialogflow.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://dialogflow.googleapis.com" + ) + + +def test_tools_client_get_transport_class(): + transport = ToolsClient.get_transport_class() + available_transports = [ + transports.ToolsGrpcTransport, + transports.ToolsRestTransport, + ] + assert transport in available_transports + + transport = ToolsClient.get_transport_class("grpc") + assert transport == transports.ToolsGrpcTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (ToolsClient, transports.ToolsGrpcTransport, "grpc"), + (ToolsAsyncClient, transports.ToolsGrpcAsyncIOTransport, "grpc_asyncio"), + (ToolsClient, transports.ToolsRestTransport, "rest"), + ], +) +@mock.patch.object( + ToolsClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ToolsClient), +) +@mock.patch.object( + ToolsAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ToolsAsyncClient), +) +def test_tools_client_client_options(client_class, transport_class, transport_name): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(ToolsClient, "get_transport_class") as gtc: + transport = transport_class(credentials=ga_credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(ToolsClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name, client_options=options) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT is + # "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client.DEFAULT_MTLS_ENDPOINT, + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client = client_class(transport=transport_name) + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + # Check the case quota_project_id is provided + options = client_options.ClientOptions(quota_project_id="octopus") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id="octopus", + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + # Check the case api_endpoint is provided + options = client_options.ClientOptions( + api_audience="https://language.googleapis.com" + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience="https://language.googleapis.com", + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,use_client_cert_env", + [ + (ToolsClient, transports.ToolsGrpcTransport, "grpc", "true"), + ( + ToolsAsyncClient, + transports.ToolsGrpcAsyncIOTransport, + "grpc_asyncio", + "true", + ), + (ToolsClient, transports.ToolsGrpcTransport, "grpc", "false"), + ( + ToolsAsyncClient, + transports.ToolsGrpcAsyncIOTransport, + "grpc_asyncio", + "false", + ), + (ToolsClient, transports.ToolsRestTransport, "rest", "true"), + (ToolsClient, transports.ToolsRestTransport, "rest", "false"), + ], +) +@mock.patch.object( + ToolsClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ToolsClient), +) +@mock.patch.object( + ToolsAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ToolsAsyncClient), +) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_tools_client_mtls_env_auto( + client_class, transport_class, transport_name, use_client_cert_env +): + # This tests the endpoint autoswitch behavior. Endpoint is autoswitched to the default + # mtls endpoint, if GOOGLE_API_USE_CLIENT_CERTIFICATE is "true" and client cert exists. + + # Check the case client_cert_source is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + + if use_client_cert_env == "false": + expected_client_cert_source = None + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + else: + expected_client_cert_source = client_cert_source_callback + expected_host = client.DEFAULT_MTLS_ENDPOINT + + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case ADC client cert is provided. Whether client cert is used depends on + # GOOGLE_API_USE_CLIENT_CERTIFICATE value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=client_cert_source_callback, + ): + if use_client_cert_env == "false": + expected_host = client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ) + expected_client_cert_source = None + else: + expected_host = client.DEFAULT_MTLS_ENDPOINT + expected_client_cert_source = client_cert_source_callback + + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=expected_host, + scopes=None, + client_cert_source_for_mtls=expected_client_cert_source, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # Check the case client_cert_source and ADC client cert are not provided. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env} + ): + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class(transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize("client_class", [ToolsClient, ToolsAsyncClient]) +@mock.patch.object( + ToolsClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ToolsClient) +) +@mock.patch.object( + ToolsAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ToolsAsyncClient) +) +def test_tools_client_get_mtls_endpoint_and_cert_source(client_class): + mock_client_cert_source = mock.Mock() + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "true". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source == mock_client_cert_source + + # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "false". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}): + mock_client_cert_source = mock.Mock() + mock_api_endpoint = "foo" + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=mock_api_endpoint + ) + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source( + options + ) + assert api_endpoint == mock_api_endpoint + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "always". + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert doesn't exist. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_ENDPOINT + assert cert_source is None + + # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "auto" and default cert exists. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + with mock.patch( + "google.auth.transport.mtls.default_client_cert_source", + return_value=mock_client_cert_source, + ): + ( + api_endpoint, + cert_source, + ) = client_class.get_mtls_endpoint_and_cert_source() + assert api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + assert cert_source == mock_client_cert_source + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS_ENDPOINT has + # unsupported value. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "Unsupported"}): + with pytest.raises(MutualTLSChannelError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value. + with mock.patch.dict( + os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"} + ): + with pytest.raises(ValueError) as excinfo: + client_class.get_mtls_endpoint_and_cert_source() + + assert ( + str(excinfo.value) + == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" + ) + + +@pytest.mark.parametrize("client_class", [ToolsClient, ToolsAsyncClient]) +@mock.patch.object( + ToolsClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ToolsClient), +) +@mock.patch.object( + ToolsAsyncClient, + "_DEFAULT_ENDPOINT_TEMPLATE", + modify_default_endpoint_template(ToolsAsyncClient), +) +def test_tools_client_client_api_endpoint(client_class): + mock_client_cert_source = client_cert_source_callback + api_override = "foo.com" + default_universe = ToolsClient._DEFAULT_UNIVERSE + default_endpoint = ToolsClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=default_universe + ) + mock_universe = "bar.com" + mock_endpoint = ToolsClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=mock_universe + ) + + # If ClientOptions.api_endpoint is set and GOOGLE_API_USE_CLIENT_CERTIFICATE="true", + # use ClientOptions.api_endpoint as the api endpoint regardless. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}): + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ): + options = client_options.ClientOptions( + client_cert_source=mock_client_cert_source, api_endpoint=api_override + ) + client = client_class( + client_options=options, + credentials=ga_credentials.AnonymousCredentials(), + ) + assert client.api_endpoint == api_override + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == default_endpoint + + # If ClientOptions.api_endpoint is not set and GOOGLE_API_USE_MTLS_ENDPOINT="always", + # use the DEFAULT_MTLS_ENDPOINT as the api endpoint. + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "always"}): + client = client_class(credentials=ga_credentials.AnonymousCredentials()) + assert client.api_endpoint == client_class.DEFAULT_MTLS_ENDPOINT + + # If ClientOptions.api_endpoint is not set, GOOGLE_API_USE_MTLS_ENDPOINT="auto" (default), + # GOOGLE_API_USE_CLIENT_CERTIFICATE="false" (default), default cert source doesn't exist, + # and ClientOptions.universe_domain="bar.com", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with universe domain as the api endpoint. + options = client_options.ClientOptions() + universe_exists = hasattr(options, "universe_domain") + if universe_exists: + options = client_options.ClientOptions(universe_domain=mock_universe) + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + else: + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == ( + mock_endpoint if universe_exists else default_endpoint + ) + assert client.universe_domain == ( + mock_universe if universe_exists else default_universe + ) + + # If ClientOptions does not have a universe domain attribute and GOOGLE_API_USE_MTLS_ENDPOINT="never", + # use the _DEFAULT_ENDPOINT_TEMPLATE populated with GDU as the api endpoint. + options = client_options.ClientOptions() + if hasattr(options, "universe_domain"): + delattr(options, "universe_domain") + with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}): + client = client_class( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + assert client.api_endpoint == default_endpoint + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (ToolsClient, transports.ToolsGrpcTransport, "grpc"), + (ToolsAsyncClient, transports.ToolsGrpcAsyncIOTransport, "grpc_asyncio"), + (ToolsClient, transports.ToolsRestTransport, "rest"), + ], +) +def test_tools_client_client_options_scopes( + client_class, transport_class, transport_name +): + # Check the case scopes are provided. + options = client_options.ClientOptions( + scopes=["1", "2"], + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=["1", "2"], + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + (ToolsClient, transports.ToolsGrpcTransport, "grpc", grpc_helpers), + ( + ToolsAsyncClient, + transports.ToolsGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + (ToolsClient, transports.ToolsRestTransport, "rest", None), + ], +) +def test_tools_client_client_options_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +def test_tools_client_client_options_from_dict(): + with mock.patch( + "google.cloud.dialogflow_v2beta1.services.tools.transports.ToolsGrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = ToolsClient(client_options={"api_endpoint": "squid.clam.whelk"}) + grpc_transport.assert_called_once_with( + credentials=None, + credentials_file=None, + host="squid.clam.whelk", + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name,grpc_helpers", + [ + (ToolsClient, transports.ToolsGrpcTransport, "grpc", grpc_helpers), + ( + ToolsAsyncClient, + transports.ToolsGrpcAsyncIOTransport, + "grpc_asyncio", + grpc_helpers_async, + ), + ], +) +def test_tools_client_create_channel_credentials_file( + client_class, transport_class, transport_name, grpc_helpers +): + # Check the case credentials file is provided. + options = client_options.ClientOptions(credentials_file="credentials.json") + + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options, transport=transport_name) + patched.assert_called_once_with( + credentials=None, + credentials_file="credentials.json", + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) + + # test that the credentials from file are saved and used as the credentials. + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel" + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + file_creds = ga_credentials.AnonymousCredentials() + load_creds.return_value = (file_creds, None) + adc.return_value = (creds, None) + client = client_class(client_options=options, transport=transport_name) + create_channel.assert_called_with( + "dialogflow.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/dialogflow", + ), + scopes=None, + default_host="dialogflow.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "request_type", + [ + gcd_tool.CreateToolRequest, + dict, + ], +) +def test_create_tool(request_type, transport: str = "grpc"): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_tool), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = gcd_tool.Tool( + name="name_value", + tool_key="tool_key_value", + display_name="display_name_value", + description="description_value", + satisfies_pzs=True, + satisfies_pzi=True, + ) + response = client.create_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = gcd_tool.CreateToolRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, gcd_tool.Tool) + assert response.name == "name_value" + assert response.tool_key == "tool_key_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.satisfies_pzs is True + assert response.satisfies_pzi is True + + +def test_create_tool_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = gcd_tool.CreateToolRequest( + parent="parent_value", + tool_id="tool_id_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_tool), "__call__") as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.create_tool(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == gcd_tool.CreateToolRequest( + parent="parent_value", + tool_id="tool_id_value", + ) + + +def test_create_tool_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.create_tool in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.create_tool] = mock_rpc + request = {} + client.create_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.create_tool(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_create_tool_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.create_tool + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.create_tool + ] = mock_rpc + + request = {} + await client.create_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.create_tool(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_create_tool_async( + transport: str = "grpc_asyncio", request_type=gcd_tool.CreateToolRequest +): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_tool), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcd_tool.Tool( + name="name_value", + tool_key="tool_key_value", + display_name="display_name_value", + description="description_value", + satisfies_pzs=True, + satisfies_pzi=True, + ) + ) + response = await client.create_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = gcd_tool.CreateToolRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, gcd_tool.Tool) + assert response.name == "name_value" + assert response.tool_key == "tool_key_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.satisfies_pzs is True + assert response.satisfies_pzi is True + + +@pytest.mark.asyncio +async def test_create_tool_async_from_dict(): + await test_create_tool_async(request_type=dict) + + +def test_create_tool_field_headers(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = gcd_tool.CreateToolRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_tool), "__call__") as call: + call.return_value = gcd_tool.Tool() + client.create_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_create_tool_field_headers_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = gcd_tool.CreateToolRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_tool), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcd_tool.Tool()) + await client.create_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_create_tool_flattened(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_tool), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = gcd_tool.Tool() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_tool( + parent="parent_value", + tool=gcd_tool.Tool(name="name_value"), + tool_id="tool_id_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].tool + mock_val = gcd_tool.Tool(name="name_value") + assert arg == mock_val + arg = args[0].tool_id + mock_val = "tool_id_value" + assert arg == mock_val + + +def test_create_tool_flattened_error(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_tool( + gcd_tool.CreateToolRequest(), + parent="parent_value", + tool=gcd_tool.Tool(name="name_value"), + tool_id="tool_id_value", + ) + + +@pytest.mark.asyncio +async def test_create_tool_flattened_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_tool), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = gcd_tool.Tool() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcd_tool.Tool()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_tool( + parent="parent_value", + tool=gcd_tool.Tool(name="name_value"), + tool_id="tool_id_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].tool + mock_val = gcd_tool.Tool(name="name_value") + assert arg == mock_val + arg = args[0].tool_id + mock_val = "tool_id_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_create_tool_flattened_error_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_tool( + gcd_tool.CreateToolRequest(), + parent="parent_value", + tool=gcd_tool.Tool(name="name_value"), + tool_id="tool_id_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + tool.GetToolRequest, + dict, + ], +) +def test_get_tool(request_type, transport: str = "grpc"): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_tool), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = tool.Tool( + name="name_value", + tool_key="tool_key_value", + display_name="display_name_value", + description="description_value", + satisfies_pzs=True, + satisfies_pzi=True, + ) + response = client.get_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = tool.GetToolRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, tool.Tool) + assert response.name == "name_value" + assert response.tool_key == "tool_key_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.satisfies_pzs is True + assert response.satisfies_pzi is True + + +def test_get_tool_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = tool.GetToolRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_tool), "__call__") as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.get_tool(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tool.GetToolRequest( + name="name_value", + ) + + +def test_get_tool_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_tool in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_tool] = mock_rpc + request = {} + client.get_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_tool(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_get_tool_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.get_tool + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.get_tool + ] = mock_rpc + + request = {} + await client.get_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.get_tool(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_get_tool_async( + transport: str = "grpc_asyncio", request_type=tool.GetToolRequest +): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_tool), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tool.Tool( + name="name_value", + tool_key="tool_key_value", + display_name="display_name_value", + description="description_value", + satisfies_pzs=True, + satisfies_pzi=True, + ) + ) + response = await client.get_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = tool.GetToolRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, tool.Tool) + assert response.name == "name_value" + assert response.tool_key == "tool_key_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.satisfies_pzs is True + assert response.satisfies_pzi is True + + +@pytest.mark.asyncio +async def test_get_tool_async_from_dict(): + await test_get_tool_async(request_type=dict) + + +def test_get_tool_field_headers(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = tool.GetToolRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_tool), "__call__") as call: + call.return_value = tool.Tool() + client.get_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_tool_field_headers_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = tool.GetToolRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_tool), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(tool.Tool()) + await client.get_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_get_tool_flattened(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_tool), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = tool.Tool() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_tool( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_get_tool_flattened_error(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_tool( + tool.GetToolRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_tool_flattened_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_tool), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = tool.Tool() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(tool.Tool()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_tool( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_get_tool_flattened_error_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_tool( + tool.GetToolRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + tool.ListToolsRequest, + dict, + ], +) +def test_list_tools(request_type, transport: str = "grpc"): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_tools), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = tool.ListToolsResponse( + next_page_token="next_page_token_value", + ) + response = client.list_tools(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = tool.ListToolsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListToolsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_tools_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = tool.ListToolsRequest( + parent="parent_value", + page_token="page_token_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_tools), "__call__") as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.list_tools(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tool.ListToolsRequest( + parent="parent_value", + page_token="page_token_value", + ) + + +def test_list_tools_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_tools in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_tools] = mock_rpc + request = {} + client.list_tools(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_tools(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_list_tools_async_use_cached_wrapped_rpc(transport: str = "grpc_asyncio"): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.list_tools + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.list_tools + ] = mock_rpc + + request = {} + await client.list_tools(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.list_tools(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_list_tools_async( + transport: str = "grpc_asyncio", request_type=tool.ListToolsRequest +): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_tools), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tool.ListToolsResponse( + next_page_token="next_page_token_value", + ) + ) + response = await client.list_tools(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = tool.ListToolsRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListToolsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_list_tools_async_from_dict(): + await test_list_tools_async(request_type=dict) + + +def test_list_tools_field_headers(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = tool.ListToolsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_tools), "__call__") as call: + call.return_value = tool.ListToolsResponse() + client.list_tools(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_tools_field_headers_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = tool.ListToolsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_tools), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tool.ListToolsResponse() + ) + await client.list_tools(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_list_tools_flattened(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_tools), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = tool.ListToolsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_tools( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +def test_list_tools_flattened_error(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_tools( + tool.ListToolsRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_tools_flattened_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_tools), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = tool.ListToolsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tool.ListToolsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_tools( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_list_tools_flattened_error_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_tools( + tool.ListToolsRequest(), + parent="parent_value", + ) + + +def test_list_tools_pager(transport_name: str = "grpc"): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_tools), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + tool.ListToolsResponse( + tools=[ + tool.Tool(), + tool.Tool(), + tool.Tool(), + ], + next_page_token="abc", + ), + tool.ListToolsResponse( + tools=[], + next_page_token="def", + ), + tool.ListToolsResponse( + tools=[ + tool.Tool(), + ], + next_page_token="ghi", + ), + tool.ListToolsResponse( + tools=[ + tool.Tool(), + tool.Tool(), + ], + ), + RuntimeError, + ) + + expected_metadata = () + retry = retries.Retry() + timeout = 5 + expected_metadata = tuple(expected_metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", ""),)), + ) + pager = client.list_tools(request={}, retry=retry, timeout=timeout) + + assert pager._metadata == expected_metadata + assert pager._retry == retry + assert pager._timeout == timeout + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, tool.Tool) for i in results) + + +def test_list_tools_pages(transport_name: str = "grpc"): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport_name, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_tools), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + tool.ListToolsResponse( + tools=[ + tool.Tool(), + tool.Tool(), + tool.Tool(), + ], + next_page_token="abc", + ), + tool.ListToolsResponse( + tools=[], + next_page_token="def", + ), + tool.ListToolsResponse( + tools=[ + tool.Tool(), + ], + next_page_token="ghi", + ), + tool.ListToolsResponse( + tools=[ + tool.Tool(), + tool.Tool(), + ], + ), + RuntimeError, + ) + pages = list(client.list_tools(request={}).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_tools_async_pager(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tools), "__call__", new_callable=mock.AsyncMock + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + tool.ListToolsResponse( + tools=[ + tool.Tool(), + tool.Tool(), + tool.Tool(), + ], + next_page_token="abc", + ), + tool.ListToolsResponse( + tools=[], + next_page_token="def", + ), + tool.ListToolsResponse( + tools=[ + tool.Tool(), + ], + next_page_token="ghi", + ), + tool.ListToolsResponse( + tools=[ + tool.Tool(), + tool.Tool(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_tools( + request={}, + ) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: # pragma: no branch + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, tool.Tool) for i in responses) + + +@pytest.mark.asyncio +async def test_list_tools_async_pages(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_tools), "__call__", new_callable=mock.AsyncMock + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + tool.ListToolsResponse( + tools=[ + tool.Tool(), + tool.Tool(), + tool.Tool(), + ], + next_page_token="abc", + ), + tool.ListToolsResponse( + tools=[], + next_page_token="def", + ), + tool.ListToolsResponse( + tools=[ + tool.Tool(), + ], + next_page_token="ghi", + ), + tool.ListToolsResponse( + tools=[ + tool.Tool(), + tool.Tool(), + ], + ), + RuntimeError, + ) + pages = [] + # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch` + # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372 + async for page_ in ( # pragma: no branch + await client.list_tools(request={}) + ).pages: + pages.append(page_) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + tool.DeleteToolRequest, + dict, + ], +) +def test_delete_tool(request_type, transport: str = "grpc"): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_tool), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = tool.DeleteToolRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_tool_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = tool.DeleteToolRequest( + name="name_value", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_tool), "__call__") as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.delete_tool(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == tool.DeleteToolRequest( + name="name_value", + ) + + +def test_delete_tool_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.delete_tool in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.delete_tool] = mock_rpc + request = {} + client.delete_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.delete_tool(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_delete_tool_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.delete_tool + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.delete_tool + ] = mock_rpc + + request = {} + await client.delete_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.delete_tool(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_delete_tool_async( + transport: str = "grpc_asyncio", request_type=tool.DeleteToolRequest +): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_tool), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = tool.DeleteToolRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_tool_async_from_dict(): + await test_delete_tool_async(request_type=dict) + + +def test_delete_tool_field_headers(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = tool.DeleteToolRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_tool), "__call__") as call: + call.return_value = None + client.delete_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_delete_tool_field_headers_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = tool.DeleteToolRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_tool), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_delete_tool_flattened(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_tool), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_tool( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_delete_tool_flattened_error(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_tool( + tool.DeleteToolRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_delete_tool_flattened_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_tool), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_tool( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_delete_tool_flattened_error_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_tool( + tool.DeleteToolRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + gcd_tool.UpdateToolRequest, + dict, + ], +) +def test_update_tool(request_type, transport: str = "grpc"): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_tool), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = gcd_tool.Tool( + name="name_value", + tool_key="tool_key_value", + display_name="display_name_value", + description="description_value", + satisfies_pzs=True, + satisfies_pzi=True, + ) + response = client.update_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + request = gcd_tool.UpdateToolRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, gcd_tool.Tool) + assert response.name == "name_value" + assert response.tool_key == "tool_key_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.satisfies_pzs is True + assert response.satisfies_pzi is True + + +def test_update_tool_non_empty_request_with_auto_populated_field(): + # This test is a coverage failsafe to make sure that UUID4 fields are + # automatically populated, according to AIP-4235, with non-empty requests. + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Populate all string fields in the request which are not UUID4 + # since we want to check that UUID4 are populated automatically + # if they meet the requirements of AIP 4235. + request = gcd_tool.UpdateToolRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_tool), "__call__") as call: + call.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client.update_tool(request=request) + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == gcd_tool.UpdateToolRequest() + + +def test_update_tool_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.update_tool in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.update_tool] = mock_rpc + request = {} + client.update_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_tool(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_update_tool_async_use_cached_wrapped_rpc( + transport: str = "grpc_asyncio", +): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method_async.wrap_method") as wrapper_fn: + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert ( + client._client._transport.update_tool + in client._client._transport._wrapped_methods + ) + + # Replace cached wrapped function with mock + mock_rpc = mock.AsyncMock() + mock_rpc.return_value = mock.Mock() + client._client._transport._wrapped_methods[ + client._client._transport.update_tool + ] = mock_rpc + + request = {} + await client.update_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + await client.update_tool(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +@pytest.mark.asyncio +async def test_update_tool_async( + transport: str = "grpc_asyncio", request_type=gcd_tool.UpdateToolRequest +): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_tool), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcd_tool.Tool( + name="name_value", + tool_key="tool_key_value", + display_name="display_name_value", + description="description_value", + satisfies_pzs=True, + satisfies_pzi=True, + ) + ) + response = await client.update_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + request = gcd_tool.UpdateToolRequest() + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, gcd_tool.Tool) + assert response.name == "name_value" + assert response.tool_key == "tool_key_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.satisfies_pzs is True + assert response.satisfies_pzi is True + + +@pytest.mark.asyncio +async def test_update_tool_async_from_dict(): + await test_update_tool_async(request_type=dict) + + +def test_update_tool_field_headers(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = gcd_tool.UpdateToolRequest() + + request.tool.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_tool), "__call__") as call: + call.return_value = gcd_tool.Tool() + client.update_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "tool.name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_tool_field_headers_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = gcd_tool.UpdateToolRequest() + + request.tool.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_tool), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcd_tool.Tool()) + await client.update_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "tool.name=name_value", + ) in kw["metadata"] + + +def test_update_tool_flattened(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_tool), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = gcd_tool.Tool() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_tool( + tool=gcd_tool.Tool(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].tool + mock_val = gcd_tool.Tool(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +def test_update_tool_flattened_error(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_tool( + gcd_tool.UpdateToolRequest(), + tool=gcd_tool.Tool(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_tool_flattened_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_tool), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = gcd_tool.Tool() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcd_tool.Tool()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_tool( + tool=gcd_tool.Tool(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].tool + mock_val = gcd_tool.Tool(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_update_tool_flattened_error_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_tool( + gcd_tool.UpdateToolRequest(), + tool=gcd_tool.Tool(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_create_tool_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.create_tool in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.create_tool] = mock_rpc + + request = {} + client.create_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.create_tool(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_create_tool_rest_required_fields(request_type=gcd_tool.CreateToolRequest): + transport_class = transports.ToolsRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_tool._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_tool._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("tool_id",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcd_tool.Tool() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gcd_tool.Tool.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.create_tool(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_create_tool_rest_unset_required_fields(): + transport = transports.ToolsRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_tool._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(("toolId",)) + & set( + ( + "parent", + "tool", + ) + ) + ) + + +def test_create_tool_rest_flattened(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcd_tool.Tool() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + tool=gcd_tool.Tool(name="name_value"), + tool_id="tool_id_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcd_tool.Tool.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.create_tool(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2beta1/{parent=projects/*/locations/*}/tools" % client.transport._host, + args[1], + ) + + +def test_create_tool_rest_flattened_error(transport: str = "rest"): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_tool( + gcd_tool.CreateToolRequest(), + parent="parent_value", + tool=gcd_tool.Tool(name="name_value"), + tool_id="tool_id_value", + ) + + +def test_get_tool_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.get_tool in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.get_tool] = mock_rpc + + request = {} + client.get_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.get_tool(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_get_tool_rest_required_fields(request_type=tool.GetToolRequest): + transport_class = transports.ToolsRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_tool._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_tool._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = tool.Tool() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = tool.Tool.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_tool(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_tool_rest_unset_required_fields(): + transport = transports.ToolsRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_tool._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_get_tool_rest_flattened(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = tool.Tool() + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "projects/sample1/locations/sample2/tools/sample3"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = tool.Tool.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.get_tool(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2beta1/{name=projects/*/locations/*/tools/*}" % client.transport._host, + args[1], + ) + + +def test_get_tool_rest_flattened_error(transport: str = "rest"): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_tool( + tool.GetToolRequest(), + name="name_value", + ) + + +def test_list_tools_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.list_tools in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.list_tools] = mock_rpc + + request = {} + client.list_tools(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.list_tools(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_list_tools_rest_required_fields(request_type=tool.ListToolsRequest): + transport_class = transports.ToolsRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_tools._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_tools._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = tool.ListToolsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = tool.ListToolsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_tools(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_tools_rest_unset_required_fields(): + transport = transports.ToolsRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_tools._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +def test_list_tools_rest_flattened(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = tool.ListToolsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {"parent": "projects/sample1/locations/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = tool.ListToolsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.list_tools(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2beta1/{parent=projects/*/locations/*}/tools" % client.transport._host, + args[1], + ) + + +def test_list_tools_rest_flattened_error(transport: str = "rest"): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_tools( + tool.ListToolsRequest(), + parent="parent_value", + ) + + +def test_list_tools_rest_pager(transport: str = "rest"): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + tool.ListToolsResponse( + tools=[ + tool.Tool(), + tool.Tool(), + tool.Tool(), + ], + next_page_token="abc", + ), + tool.ListToolsResponse( + tools=[], + next_page_token="def", + ), + tool.ListToolsResponse( + tools=[ + tool.Tool(), + ], + next_page_token="ghi", + ), + tool.ListToolsResponse( + tools=[ + tool.Tool(), + tool.Tool(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(tool.ListToolsResponse.to_json(x) for x in response) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = {"parent": "projects/sample1/locations/sample2"} + + pager = client.list_tools(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, tool.Tool) for i in results) + + pages = list(client.list_tools(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +def test_delete_tool_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.delete_tool in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.delete_tool] = mock_rpc + + request = {} + client.delete_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.delete_tool(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_delete_tool_rest_required_fields(request_type=tool.DeleteToolRequest): + transport_class = transports.ToolsRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_tool._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_tool._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.delete_tool(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_delete_tool_rest_unset_required_fields(): + transport = transports.ToolsRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_tool._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +def test_delete_tool_rest_flattened(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "projects/sample1/locations/sample2/tools/sample3"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.delete_tool(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2beta1/{name=projects/*/locations/*/tools/*}" % client.transport._host, + args[1], + ) + + +def test_delete_tool_rest_flattened_error(transport: str = "rest"): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_tool( + tool.DeleteToolRequest(), + name="name_value", + ) + + +def test_update_tool_rest_use_cached_wrapped_rpc(): + # Clients should use _prep_wrapped_messages to create cached wrapped rpcs, + # instead of constructing them on each call + with mock.patch("google.api_core.gapic_v1.method.wrap_method") as wrapper_fn: + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Should wrap all calls on client creation + assert wrapper_fn.call_count > 0 + wrapper_fn.reset_mock() + + # Ensure method has been cached + assert client._transport.update_tool in client._transport._wrapped_methods + + # Replace cached wrapped function with mock + mock_rpc = mock.Mock() + mock_rpc.return_value.name = ( + "foo" # operation_request.operation in compute client(s) expect a string. + ) + client._transport._wrapped_methods[client._transport.update_tool] = mock_rpc + + request = {} + client.update_tool(request) + + # Establish that the underlying gRPC stub method was called. + assert mock_rpc.call_count == 1 + + client.update_tool(request) + + # Establish that a new wrapper was not created for this call + assert wrapper_fn.call_count == 0 + assert mock_rpc.call_count == 2 + + +def test_update_tool_rest_required_fields(request_type=gcd_tool.UpdateToolRequest): + transport_class = transports.ToolsRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_tool._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_tool._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcd_tool.Tool() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gcd_tool.Tool.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.update_tool(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_tool_rest_unset_required_fields(): + transport = transports.ToolsRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_tool._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("tool",))) + + +def test_update_tool_rest_flattened(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcd_tool.Tool() + + # get arguments that satisfy an http rule for this method + sample_request = { + "tool": {"name": "projects/sample1/locations/sample2/tools/sample3"} + } + + # get truthy value for each flattened field + mock_args = dict( + tool=gcd_tool.Tool(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = gcd_tool.Tool.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + client.update_tool(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v2beta1/{tool.name=projects/*/locations/*/tools/*}" + % client.transport._host, + args[1], + ) + + +def test_update_tool_rest_flattened_error(transport: str = "rest"): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_tool( + gcd_tool.UpdateToolRequest(), + tool=gcd_tool.Tool(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ToolsGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ToolsGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ToolsClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ToolsGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ToolsClient( + client_options=options, + transport=transport, + ) + + # It is an error to provide an api_key and a credential. + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ToolsClient( + client_options=options, credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ToolsGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ToolsClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ToolsGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ToolsClient(transport=transport) + assert client.transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ToolsGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ToolsGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ToolsGrpcTransport, + transports.ToolsGrpcAsyncIOTransport, + transports.ToolsRestTransport, + ], +) +def test_transport_adc(transport_class): + # Test default credentials are used if not provided. + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class() + adc.assert_called_once() + + +def test_transport_kind_grpc(): + transport = ToolsClient.get_transport_class("grpc")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "grpc" + + +def test_initialize_client_w_grpc(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_tool_empty_call_grpc(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_tool), "__call__") as call: + call.return_value = gcd_tool.Tool() + client.create_tool(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcd_tool.CreateToolRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_tool_empty_call_grpc(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_tool), "__call__") as call: + call.return_value = tool.Tool() + client.get_tool(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = tool.GetToolRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_tools_empty_call_grpc(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_tools), "__call__") as call: + call.return_value = tool.ListToolsResponse() + client.list_tools(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = tool.ListToolsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_tool_empty_call_grpc(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_tool), "__call__") as call: + call.return_value = None + client.delete_tool(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = tool.DeleteToolRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_tool_empty_call_grpc(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_tool), "__call__") as call: + call.return_value = gcd_tool.Tool() + client.update_tool(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcd_tool.UpdateToolRequest() + + assert args[0] == request_msg + + +def test_transport_kind_grpc_asyncio(): + transport = ToolsAsyncClient.get_transport_class("grpc_asyncio")( + credentials=async_anonymous_credentials() + ) + assert transport.kind == "grpc_asyncio" + + +def test_initialize_client_w_grpc_asyncio(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_create_tool_empty_call_grpc_asyncio(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_tool), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcd_tool.Tool( + name="name_value", + tool_key="tool_key_value", + display_name="display_name_value", + description="description_value", + satisfies_pzs=True, + satisfies_pzi=True, + ) + ) + await client.create_tool(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcd_tool.CreateToolRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_get_tool_empty_call_grpc_asyncio(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_tool), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tool.Tool( + name="name_value", + tool_key="tool_key_value", + display_name="display_name_value", + description="description_value", + satisfies_pzs=True, + satisfies_pzi=True, + ) + ) + await client.get_tool(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = tool.GetToolRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_list_tools_empty_call_grpc_asyncio(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_tools), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + tool.ListToolsResponse( + next_page_token="next_page_token_value", + ) + ) + await client.list_tools(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = tool.ListToolsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_delete_tool_empty_call_grpc_asyncio(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_tool), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_tool(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = tool.DeleteToolRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +@pytest.mark.asyncio +async def test_update_tool_empty_call_grpc_asyncio(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + transport="grpc_asyncio", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_tool), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + gcd_tool.Tool( + name="name_value", + tool_key="tool_key_value", + display_name="display_name_value", + description="description_value", + satisfies_pzs=True, + satisfies_pzi=True, + ) + ) + await client.update_tool(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcd_tool.UpdateToolRequest() + + assert args[0] == request_msg + + +def test_transport_kind_rest(): + transport = ToolsClient.get_transport_class("rest")( + credentials=ga_credentials.AnonymousCredentials() + ) + assert transport.kind == "rest" + + +def test_create_tool_rest_bad_request(request_type=gcd_tool.CreateToolRequest): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.create_tool(request) + + +@pytest.mark.parametrize( + "request_type", + [ + gcd_tool.CreateToolRequest, + dict, + ], +) +def test_create_tool_rest_call_success(request_type): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request_init["tool"] = { + "name": "name_value", + "tool_key": "tool_key_value", + "display_name": "display_name_value", + "description": "description_value", + "action_confirmation_requirement": {}, + "extension_spec": {"name": "name_value"}, + "function_spec": { + "input_schema": {"fields": {}}, + "output_schema": {}, + "method_type": 1, + }, + "connector_spec": { + "name": "name_value", + "actions": [ + { + "connection_action_id": "connection_action_id_value", + "entity_operation": { + "entity_id": "entity_id_value", + "operation": 1, + }, + "input_fields": ["input_fields_value1", "input_fields_value2"], + "output_fields": ["output_fields_value1", "output_fields_value2"], + } + ], + }, + "open_api_spec": { + "text_schema": "text_schema_value", + "authentication": { + "api_key_config": { + "key_name": "key_name_value", + "api_key": "api_key_value", + "secret_version_for_api_key": "secret_version_for_api_key_value", + "request_location": 1, + }, + "oauth_config": { + "oauth_grant_type": 1, + "client_id": "client_id_value", + "client_secret": "client_secret_value", + "secret_version_for_client_secret": "secret_version_for_client_secret_value", + "token_endpoint": "token_endpoint_value", + "scopes": ["scopes_value1", "scopes_value2"], + }, + "service_agent_auth_config": {"service_agent_auth": 1}, + "bearer_token_config": { + "token": "token_value", + "secret_version_for_token": "secret_version_for_token_value", + }, + }, + "tls_config": { + "ca_certs": [ + {"display_name": "display_name_value", "cert": b"cert_blob"} + ] + }, + "service_directory_config": {"service": "service_value"}, + }, + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "satisfies_pzs": True, + "satisfies_pzi": True, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = gcd_tool.CreateToolRequest.meta.fields["tool"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["tool"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["tool"][field])): + del request_init["tool"][field][i][subfield] + else: + del request_init["tool"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcd_tool.Tool( + name="name_value", + tool_key="tool_key_value", + display_name="display_name_value", + description="description_value", + satisfies_pzs=True, + satisfies_pzi=True, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gcd_tool.Tool.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.create_tool(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcd_tool.Tool) + assert response.name == "name_value" + assert response.tool_key == "tool_key_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.satisfies_pzs is True + assert response.satisfies_pzi is True + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_tool_rest_interceptors(null_interceptor): + transport = transports.ToolsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ToolsRestInterceptor(), + ) + client = ToolsClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ToolsRestInterceptor, "post_create_tool" + ) as post, mock.patch.object( + transports.ToolsRestInterceptor, "post_create_tool_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.ToolsRestInterceptor, "pre_create_tool" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = gcd_tool.CreateToolRequest.pb(gcd_tool.CreateToolRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = gcd_tool.Tool.to_json(gcd_tool.Tool()) + req.return_value.content = return_value + + request = gcd_tool.CreateToolRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcd_tool.Tool() + post_with_metadata.return_value = gcd_tool.Tool(), metadata + + client.create_tool( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_tool_rest_bad_request(request_type=tool.GetToolRequest): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/locations/sample2/tools/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_tool(request) + + +@pytest.mark.parametrize( + "request_type", + [ + tool.GetToolRequest, + dict, + ], +) +def test_get_tool_rest_call_success(request_type): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/locations/sample2/tools/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = tool.Tool( + name="name_value", + tool_key="tool_key_value", + display_name="display_name_value", + description="description_value", + satisfies_pzs=True, + satisfies_pzi=True, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = tool.Tool.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.get_tool(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, tool.Tool) + assert response.name == "name_value" + assert response.tool_key == "tool_key_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.satisfies_pzs is True + assert response.satisfies_pzi is True + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_tool_rest_interceptors(null_interceptor): + transport = transports.ToolsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ToolsRestInterceptor(), + ) + client = ToolsClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ToolsRestInterceptor, "post_get_tool" + ) as post, mock.patch.object( + transports.ToolsRestInterceptor, "post_get_tool_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.ToolsRestInterceptor, "pre_get_tool" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = tool.GetToolRequest.pb(tool.GetToolRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = tool.Tool.to_json(tool.Tool()) + req.return_value.content = return_value + + request = tool.GetToolRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = tool.Tool() + post_with_metadata.return_value = tool.Tool(), metadata + + client.get_tool( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_list_tools_rest_bad_request(request_type=tool.ListToolsRequest): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_tools(request) + + +@pytest.mark.parametrize( + "request_type", + [ + tool.ListToolsRequest, + dict, + ], +) +def test_list_tools_rest_call_success(request_type): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = tool.ListToolsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = tool.ListToolsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.list_tools(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListToolsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_tools_rest_interceptors(null_interceptor): + transport = transports.ToolsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ToolsRestInterceptor(), + ) + client = ToolsClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ToolsRestInterceptor, "post_list_tools" + ) as post, mock.patch.object( + transports.ToolsRestInterceptor, "post_list_tools_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.ToolsRestInterceptor, "pre_list_tools" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = tool.ListToolsRequest.pb(tool.ListToolsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = tool.ListToolsResponse.to_json(tool.ListToolsResponse()) + req.return_value.content = return_value + + request = tool.ListToolsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = tool.ListToolsResponse() + post_with_metadata.return_value = tool.ListToolsResponse(), metadata + + client.list_tools( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_delete_tool_rest_bad_request(request_type=tool.DeleteToolRequest): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/locations/sample2/tools/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.delete_tool(request) + + +@pytest.mark.parametrize( + "request_type", + [ + tool.DeleteToolRequest, + dict, + ], +) +def test_delete_tool_rest_call_success(request_type): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/locations/sample2/tools/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = "" + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.delete_tool(request) + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_tool_rest_interceptors(null_interceptor): + transport = transports.ToolsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ToolsRestInterceptor(), + ) + client = ToolsClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ToolsRestInterceptor, "pre_delete_tool" + ) as pre: + pre.assert_not_called() + pb_message = tool.DeleteToolRequest.pb(tool.DeleteToolRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + request = tool.DeleteToolRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_tool( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + + +def test_update_tool_rest_bad_request(request_type=gcd_tool.UpdateToolRequest): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + # send a request that will satisfy transcoding + request_init = { + "tool": {"name": "projects/sample1/locations/sample2/tools/sample3"} + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = mock.Mock() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = mock.Mock() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.update_tool(request) + + +@pytest.mark.parametrize( + "request_type", + [ + gcd_tool.UpdateToolRequest, + dict, + ], +) +def test_update_tool_rest_call_success(request_type): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + # send a request that will satisfy transcoding + request_init = { + "tool": {"name": "projects/sample1/locations/sample2/tools/sample3"} + } + request_init["tool"] = { + "name": "projects/sample1/locations/sample2/tools/sample3", + "tool_key": "tool_key_value", + "display_name": "display_name_value", + "description": "description_value", + "action_confirmation_requirement": {}, + "extension_spec": {"name": "name_value"}, + "function_spec": { + "input_schema": {"fields": {}}, + "output_schema": {}, + "method_type": 1, + }, + "connector_spec": { + "name": "name_value", + "actions": [ + { + "connection_action_id": "connection_action_id_value", + "entity_operation": { + "entity_id": "entity_id_value", + "operation": 1, + }, + "input_fields": ["input_fields_value1", "input_fields_value2"], + "output_fields": ["output_fields_value1", "output_fields_value2"], + } + ], + }, + "open_api_spec": { + "text_schema": "text_schema_value", + "authentication": { + "api_key_config": { + "key_name": "key_name_value", + "api_key": "api_key_value", + "secret_version_for_api_key": "secret_version_for_api_key_value", + "request_location": 1, + }, + "oauth_config": { + "oauth_grant_type": 1, + "client_id": "client_id_value", + "client_secret": "client_secret_value", + "secret_version_for_client_secret": "secret_version_for_client_secret_value", + "token_endpoint": "token_endpoint_value", + "scopes": ["scopes_value1", "scopes_value2"], + }, + "service_agent_auth_config": {"service_agent_auth": 1}, + "bearer_token_config": { + "token": "token_value", + "secret_version_for_token": "secret_version_for_token_value", + }, + }, + "tls_config": { + "ca_certs": [ + {"display_name": "display_name_value", "cert": b"cert_blob"} + ] + }, + "service_directory_config": {"service": "service_value"}, + }, + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "satisfies_pzs": True, + "satisfies_pzi": True, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = gcd_tool.UpdateToolRequest.meta.fields["tool"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["tool"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["tool"][field])): + del request_init["tool"][field][i][subfield] + else: + del request_init["tool"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = gcd_tool.Tool( + name="name_value", + tool_key="tool_key_value", + display_name="display_name_value", + description="description_value", + satisfies_pzs=True, + satisfies_pzi=True, + ) + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = gcd_tool.Tool.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + response = client.update_tool(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcd_tool.Tool) + assert response.name == "name_value" + assert response.tool_key == "tool_key_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.satisfies_pzs is True + assert response.satisfies_pzi is True + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_tool_rest_interceptors(null_interceptor): + transport = transports.ToolsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ToolsRestInterceptor(), + ) + client = ToolsClient(transport=transport) + + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.ToolsRestInterceptor, "post_update_tool" + ) as post, mock.patch.object( + transports.ToolsRestInterceptor, "post_update_tool_with_metadata" + ) as post_with_metadata, mock.patch.object( + transports.ToolsRestInterceptor, "pre_update_tool" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + post_with_metadata.assert_not_called() + pb_message = gcd_tool.UpdateToolRequest.pb(gcd_tool.UpdateToolRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = mock.Mock() + req.return_value.status_code = 200 + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + return_value = gcd_tool.Tool.to_json(gcd_tool.Tool()) + req.return_value.content = return_value + + request = gcd_tool.UpdateToolRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcd_tool.Tool() + post_with_metadata.return_value = gcd_tool.Tool(), metadata + + client.update_tool( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + post_with_metadata.assert_called_once() + + +def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "projects/sample1/locations/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_location(request) + + +@pytest.mark.parametrize( + "request_type", + [ + locations_pb2.GetLocationRequest, + dict, + ], +) +def test_get_location_rest(request_type): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "projects/sample1/locations/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = locations_pb2.Location() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_location(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.Location) + + +def test_list_locations_rest_bad_request( + request_type=locations_pb2.ListLocationsRequest, +): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict({"name": "projects/sample1"}, request) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_locations(request) + + +@pytest.mark.parametrize( + "request_type", + [ + locations_pb2.ListLocationsRequest, + dict, + ], +) +def test_list_locations_rest(request_type): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "projects/sample1"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = locations_pb2.ListLocationsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_locations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.ListLocationsResponse) + + +def test_cancel_operation_rest_bad_request( + request_type=operations_pb2.CancelOperationRequest, +): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "projects/sample1/operations/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.cancel_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.CancelOperationRequest, + dict, + ], +) +def test_cancel_operation_rest(request_type): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "projects/sample1/operations/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = "{}" + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.cancel_operation(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_get_operation_rest_bad_request( + request_type=operations_pb2.GetOperationRequest, +): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict( + {"name": "projects/sample1/operations/sample2"}, request + ) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.get_operation(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.GetOperationRequest, + dict, + ], +) +def test_get_operation_rest(request_type): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "projects/sample1/operations/sample2"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_list_operations_rest_bad_request( + request_type=operations_pb2.ListOperationsRequest, +): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type() + request = json_format.ParseDict({"name": "projects/sample1"}, request) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + json_return_value = "" + response_value.json = mock.Mock(return_value={}) + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + client.list_operations(request) + + +@pytest.mark.parametrize( + "request_type", + [ + operations_pb2.ListOperationsRequest, + dict, + ], +) +def test_list_operations_rest(request_type): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + request_init = {"name": "projects/sample1"} + request = request_type(**request_init) + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.ListOperationsResponse() + + # Wrap the value into a proper Response obj + response_value = mock.Mock() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value.content = json_return_value.encode("UTF-8") + + req.return_value = response_value + req.return_value.headers = {"header-1": "value-1", "header-2": "value-2"} + + response = client.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_initialize_client_w_rest(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + assert client is not None + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_create_tool_empty_call_rest(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.create_tool), "__call__") as call: + client.create_tool(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcd_tool.CreateToolRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_get_tool_empty_call_rest(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.get_tool), "__call__") as call: + client.get_tool(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = tool.GetToolRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_list_tools_empty_call_rest(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.list_tools), "__call__") as call: + client.list_tools(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = tool.ListToolsRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_delete_tool_empty_call_rest(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.delete_tool), "__call__") as call: + client.delete_tool(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = tool.DeleteToolRequest() + + assert args[0] == request_msg + + +# This test is a coverage failsafe to make sure that totally empty calls, +# i.e. request == None and no flattened fields passed, work. +def test_update_tool_empty_call_rest(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the actual call, and fake the request. + with mock.patch.object(type(client.transport.update_tool), "__call__") as call: + client.update_tool(request=None) + + # Establish that the underlying stub method was called. + call.assert_called() + _, args, _ = call.mock_calls[0] + request_msg = gcd_tool.UpdateToolRequest() + + assert args[0] == request_msg + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ToolsGrpcTransport, + ) + + +def test_tools_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ToolsTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) + + +def test_tools_base_transport(): + # Instantiate the base transport. + with mock.patch( + "google.cloud.dialogflow_v2beta1.services.tools.transports.ToolsTransport.__init__" + ) as Transport: + Transport.return_value = None + transport = transports.ToolsTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "create_tool", + "get_tool", + "list_tools", + "delete_tool", + "update_tool", + "get_location", + "list_locations", + "get_operation", + "cancel_operation", + "list_operations", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + with pytest.raises(NotImplementedError): + transport.close() + + # Catch all for all remaining methods and properties + remainder = [ + "kind", + ] + for r in remainder: + with pytest.raises(NotImplementedError): + getattr(transport, r)() + + +def test_tools_base_transport_with_credentials_file(): + # Instantiate the base transport with a credentials file + with mock.patch.object( + google.auth, "load_credentials_from_file", autospec=True + ) as load_creds, mock.patch( + "google.cloud.dialogflow_v2beta1.services.tools.transports.ToolsTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ToolsTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) + load_creds.assert_called_once_with( + "credentials.json", + scopes=None, + default_scopes=( + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/dialogflow", + ), + quota_project_id="octopus", + ) + + +def test_tools_base_transport_with_adc(): + # Test the default credentials are used if credentials and credentials_file are None. + with mock.patch.object(google.auth, "default", autospec=True) as adc, mock.patch( + "google.cloud.dialogflow_v2beta1.services.tools.transports.ToolsTransport._prep_wrapped_messages" + ) as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ToolsTransport() + adc.assert_called_once() + + +def test_tools_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + ToolsClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/dialogflow", + ), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ToolsGrpcTransport, + transports.ToolsGrpcAsyncIOTransport, + ], +) +def test_tools_transport_auth_adc(transport_class): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(google.auth, "default", autospec=True) as adc: + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + adc.assert_called_once_with( + scopes=["1", "2"], + default_scopes=( + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/dialogflow", + ), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ToolsGrpcTransport, + transports.ToolsGrpcAsyncIOTransport, + transports.ToolsRestTransport, + ], +) +def test_tools_transport_auth_gdch_credentials(transport_class): + host = "https://language.com" + api_audience_tests = [None, "https://language2.com"] + api_audience_expect = [host, "https://language2.com"] + for t, e in zip(api_audience_tests, api_audience_expect): + with mock.patch.object(google.auth, "default", autospec=True) as adc: + gdch_mock = mock.MagicMock() + type(gdch_mock).with_gdch_audience = mock.PropertyMock( + return_value=gdch_mock + ) + adc.return_value = (gdch_mock, None) + transport_class(host=host, api_audience=t) + gdch_mock.with_gdch_audience.assert_called_once_with(e) + + +@pytest.mark.parametrize( + "transport_class,grpc_helpers", + [ + (transports.ToolsGrpcTransport, grpc_helpers), + (transports.ToolsGrpcAsyncIOTransport, grpc_helpers_async), + ], +) +def test_tools_transport_create_channel(transport_class, grpc_helpers): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object( + google.auth, "default", autospec=True + ) as adc, mock.patch.object( + grpc_helpers, "create_channel", autospec=True + ) as create_channel: + creds = ga_credentials.AnonymousCredentials() + adc.return_value = (creds, None) + transport_class(quota_project_id="octopus", scopes=["1", "2"]) + + create_channel.assert_called_with( + "dialogflow.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/dialogflow", + ), + scopes=["1", "2"], + default_host="dialogflow.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize( + "transport_class", + [transports.ToolsGrpcTransport, transports.ToolsGrpcAsyncIOTransport], +) +def test_tools_grpc_transport_client_cert_source_for_mtls(transport_class): + cred = ga_credentials.AnonymousCredentials() + + # Check ssl_channel_credentials is used if provided. + with mock.patch.object(transport_class, "create_channel") as mock_create_channel: + mock_ssl_channel_creds = mock.Mock() + transport_class( + host="squid.clam.whelk", + credentials=cred, + ssl_channel_credentials=mock_ssl_channel_creds, + ) + mock_create_channel.assert_called_once_with( + "squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_channel_creds, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls + # is used. + with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()): + with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred: + transport_class( + credentials=cred, + client_cert_source_for_mtls=client_cert_source_callback, + ) + expected_cert, expected_key = client_cert_source_callback() + mock_ssl_cred.assert_called_once_with( + certificate_chain=expected_cert, private_key=expected_key + ) + + +def test_tools_http_transport_client_cert_source_for_mtls(): + cred = ga_credentials.AnonymousCredentials() + with mock.patch( + "google.auth.transport.requests.AuthorizedSession.configure_mtls_channel" + ) as mock_configure_mtls_channel: + transports.ToolsRestTransport( + credentials=cred, client_cert_source_for_mtls=client_cert_source_callback + ) + mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_tools_host_no_port(transport_name): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="dialogflow.googleapis.com" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "dialogflow.googleapis.com:443" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://dialogflow.googleapis.com" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "grpc", + "grpc_asyncio", + "rest", + ], +) +def test_tools_host_with_port(transport_name): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="dialogflow.googleapis.com:8000" + ), + transport=transport_name, + ) + assert client.transport._host == ( + "dialogflow.googleapis.com:8000" + if transport_name in ["grpc", "grpc_asyncio"] + else "https://dialogflow.googleapis.com:8000" + ) + + +@pytest.mark.parametrize( + "transport_name", + [ + "rest", + ], +) +def test_tools_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ToolsClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ToolsClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.create_tool._session + session2 = client2.transport.create_tool._session + assert session1 != session2 + session1 = client1.transport.get_tool._session + session2 = client2.transport.get_tool._session + assert session1 != session2 + session1 = client1.transport.list_tools._session + session2 = client2.transport.list_tools._session + assert session1 != session2 + session1 = client1.transport.delete_tool._session + session2 = client2.transport.delete_tool._session + assert session1 != session2 + session1 = client1.transport.update_tool._session + session2 = client2.transport.update_tool._session + assert session1 != session2 + + +def test_tools_grpc_transport_channel(): + channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ToolsGrpcTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +def test_tools_grpc_asyncio_transport_channel(): + channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ToolsGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert transport._ssl_channel_credentials == None + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize( + "transport_class", + [transports.ToolsGrpcTransport, transports.ToolsGrpcAsyncIOTransport], +) +def test_tools_transport_channel_mtls_with_client_cert_source(transport_class): + with mock.patch( + "grpc.ssl_channel_credentials", autospec=True + ) as grpc_ssl_channel_cred: + with mock.patch.object( + transport_class, "create_channel" + ) as grpc_create_channel: + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + cred = ga_credentials.AnonymousCredentials() + with pytest.warns(DeprecationWarning): + with mock.patch.object(google.auth, "default") as adc: + adc.return_value = (cred, None) + transport = transport_class( + host="squid.clam.whelk", + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + adc.assert_called_once() + + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + assert transport._ssl_channel_credentials == mock_ssl_cred + + +# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are +# removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.parametrize( + "transport_class", + [transports.ToolsGrpcTransport, transports.ToolsGrpcAsyncIOTransport], +) +def test_tools_transport_channel_mtls_with_adc(transport_class): + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + with mock.patch.object( + transport_class, "create_channel" + ) as grpc_create_channel: + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + mock_cred = mock.Mock() + + with pytest.warns(DeprecationWarning): + transport = transport_class( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=None, + ) + + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + credentials_file=None, + scopes=None, + ssl_credentials=mock_ssl_cred, + quota_project_id=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_secret_version_path(): + project = "squid" + secret = "clam" + version = "whelk" + expected = "projects/{project}/secrets/{secret}/versions/{version}".format( + project=project, + secret=secret, + version=version, + ) + actual = ToolsClient.secret_version_path(project, secret, version) + assert expected == actual + + +def test_parse_secret_version_path(): + expected = { + "project": "octopus", + "secret": "oyster", + "version": "nudibranch", + } + path = ToolsClient.secret_version_path(**expected) + + # Check that the path construction is reversible. + actual = ToolsClient.parse_secret_version_path(path) + assert expected == actual + + +def test_service_path(): + project = "cuttlefish" + location = "mussel" + namespace = "winkle" + service = "nautilus" + expected = "projects/{project}/locations/{location}/namespaces/{namespace}/services/{service}".format( + project=project, + location=location, + namespace=namespace, + service=service, + ) + actual = ToolsClient.service_path(project, location, namespace, service) + assert expected == actual + + +def test_parse_service_path(): + expected = { + "project": "scallop", + "location": "abalone", + "namespace": "squid", + "service": "clam", + } + path = ToolsClient.service_path(**expected) + + # Check that the path construction is reversible. + actual = ToolsClient.parse_service_path(path) + assert expected == actual + + +def test_tool_path(): + project = "whelk" + location = "octopus" + tool = "oyster" + expected = "projects/{project}/locations/{location}/tools/{tool}".format( + project=project, + location=location, + tool=tool, + ) + actual = ToolsClient.tool_path(project, location, tool) + assert expected == actual + + +def test_parse_tool_path(): + expected = { + "project": "nudibranch", + "location": "cuttlefish", + "tool": "mussel", + } + path = ToolsClient.tool_path(**expected) + + # Check that the path construction is reversible. + actual = ToolsClient.parse_tool_path(path) + assert expected == actual + + +def test_common_billing_account_path(): + billing_account = "winkle" + expected = "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + actual = ToolsClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "nautilus", + } + path = ToolsClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ToolsClient.parse_common_billing_account_path(path) + assert expected == actual + + +def test_common_folder_path(): + folder = "scallop" + expected = "folders/{folder}".format( + folder=folder, + ) + actual = ToolsClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "abalone", + } + path = ToolsClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ToolsClient.parse_common_folder_path(path) + assert expected == actual + + +def test_common_organization_path(): + organization = "squid" + expected = "organizations/{organization}".format( + organization=organization, + ) + actual = ToolsClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "clam", + } + path = ToolsClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ToolsClient.parse_common_organization_path(path) + assert expected == actual + + +def test_common_project_path(): + project = "whelk" + expected = "projects/{project}".format( + project=project, + ) + actual = ToolsClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "octopus", + } + path = ToolsClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ToolsClient.parse_common_project_path(path) + assert expected == actual + + +def test_common_location_path(): + project = "oyster" + location = "nudibranch" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = ToolsClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "cuttlefish", + "location": "mussel", + } + path = ToolsClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ToolsClient.parse_common_location_path(path) + assert expected == actual + + +def test_client_with_default_client_info(): + client_info = gapic_v1.client_info.ClientInfo() + + with mock.patch.object(transports.ToolsTransport, "_prep_wrapped_messages") as prep: + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ToolsTransport, "_prep_wrapped_messages") as prep: + transport_class = ToolsClient.get_transport_class() + transport = transport_class( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + +def test_cancel_operation(transport: str = "grpc"): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.CancelOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_cancel_operation_async(transport: str = "grpc_asyncio"): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.CancelOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +def test_cancel_operation_field_headers(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.CancelOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + call.return_value = None + + client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_cancel_operation_field_headers_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.CancelOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.cancel_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_cancel_operation_from_dict(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + + response = client.cancel_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_cancel_operation_from_dict_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.cancel_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.cancel_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_get_operation(transport: str = "grpc"): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc_asyncio"): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + + +def test_get_operation_field_headers(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_get_operation_from_dict(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc_asyncio"): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_list_operations_field_headers(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_list_operations_from_dict(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_locations(transport: str = "grpc"): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = locations_pb2.ListLocationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.ListLocationsResponse() + response = client.list_locations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.ListLocationsResponse) + + +@pytest.mark.asyncio +async def test_list_locations_async(transport: str = "grpc_asyncio"): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = locations_pb2.ListLocationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + response = await client.list_locations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.ListLocationsResponse) + + +def test_list_locations_field_headers(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = locations_pb2.ListLocationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + call.return_value = locations_pb2.ListLocationsResponse() + + client.list_locations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_locations_field_headers_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = locations_pb2.ListLocationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + await client.list_locations(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations", + ) in kw["metadata"] + + +def test_list_locations_from_dict(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.ListLocationsResponse() + + response = client.list_locations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_list_locations_from_dict_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.ListLocationsResponse() + ) + response = await client.list_locations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_get_location(transport: str = "grpc"): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = locations_pb2.GetLocationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.Location() + response = client.get_location(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.Location) + + +@pytest.mark.asyncio +async def test_get_location_async(transport: str = "grpc_asyncio"): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = locations_pb2.GetLocationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + response = await client.get_location(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, locations_pb2.Location) + + +def test_get_location_field_headers(): + client = ToolsClient(credentials=ga_credentials.AnonymousCredentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = locations_pb2.GetLocationRequest() + request.name = "locations/abc" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + call.return_value = locations_pb2.Location() + + client.get_location(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations/abc", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_location_field_headers_async(): + client = ToolsAsyncClient(credentials=async_anonymous_credentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = locations_pb2.GetLocationRequest() + request.name = "locations/abc" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_location), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + await client.get_location(request) + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=locations/abc", + ) in kw["metadata"] + + +def test_get_location_from_dict(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = locations_pb2.Location() + + response = client.get_location( + request={ + "name": "locations/abc", + } + ) + call.assert_called() + + +@pytest.mark.asyncio +async def test_get_location_from_dict_async(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_locations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + locations_pb2.Location() + ) + response = await client.get_location( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close_grpc(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="grpc" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +@pytest.mark.asyncio +async def test_transport_close_grpc_asyncio(): + client = ToolsAsyncClient( + credentials=async_anonymous_credentials(), transport="grpc_asyncio" + ) + with mock.patch.object( + type(getattr(client.transport, "_grpc_channel")), "close" + ) as close: + async with client: + close.assert_not_called() + close.assert_called_once() + + +def test_transport_close_rest(): + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + with mock.patch.object( + type(getattr(client.transport, "_session")), "close" + ) as close: + with client: + close.assert_not_called() + close.assert_called_once() + + +def test_client_ctx(): + transports = [ + "rest", + "grpc", + ] + for transport in transports: + client = ToolsClient( + credentials=ga_credentials.AnonymousCredentials(), transport=transport + ) + # Test client calls underlying transport. + with mock.patch.object(type(client.transport), "close") as close: + close.assert_not_called() + with client: + pass + close.assert_called() + + +@pytest.mark.parametrize( + "client_class,transport_class", + [ + (ToolsClient, transports.ToolsGrpcTransport), + (ToolsAsyncClient, transports.ToolsGrpcAsyncIOTransport), + ], +) +def test_api_key_credentials(client_class, transport_class): + with mock.patch.object( + google.auth._default, "get_api_key_credentials", create=True + ) as get_api_key_credentials: + mock_cred = mock.Mock() + get_api_key_credentials.return_value = mock_cred + options = client_options.ClientOptions() + options.api_key = "api_key" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + credentials=mock_cred, + credentials_file=None, + host=client._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=client._DEFAULT_UNIVERSE + ), + scopes=None, + client_cert_source_for_mtls=None, + quota_project_id=None, + client_info=transports.base.DEFAULT_CLIENT_INFO, + always_use_jwt_access=True, + api_audience=None, + ) diff --git a/packages/google-maps-places/google/maps/places_v1/types/place.py b/packages/google-maps-places/google/maps/places_v1/types/place.py index 04848238424b..ec58c8b2ba52 100644 --- a/packages/google-maps-places/google/maps/places_v1/types/place.py +++ b/packages/google-maps-places/google/maps/places_v1/types/place.py @@ -395,6 +395,10 @@ class Place(proto.Message): neighborhood_summary (google.maps.places_v1.types.Place.NeighborhoodSummary): A summary of points of interest near the place. + consumer_alert (google.maps.places_v1.types.Place.ConsumerAlert): + The consumer alert message for the place when + we detect suspicious review activity on a + business or a business violates our policies. moved_place (str): If this Place is permanently closed and has moved to a new Place, this field contains the new Place's resource name, in @@ -1139,6 +1143,84 @@ class NeighborhoodSummary(proto.Message): message=localized_text_pb2.LocalizedText, ) + class ConsumerAlert(proto.Message): + r"""The consumer alert message for the place when we detect + suspicious review activity on a business or a business violates + our policies. + + Attributes: + overview (str): + The overview of the consumer alert message. + details (google.maps.places_v1.types.Place.ConsumerAlert.Details): + The details of the consumer alert message. + language_code (str): + The language code of the consumer alert + message. This is a BCP 47 language code. + """ + + class Details(proto.Message): + r"""The details of the consumer alert message. + + Attributes: + title (str): + The title to show together with the + description. + description (str): + The description of the consumer alert + message. + about_link (google.maps.places_v1.types.Place.ConsumerAlert.Details.Link): + The link to show together with the + description to provide more information. + """ + + class Link(proto.Message): + r"""The link to show together with the description to provide + more information. + + Attributes: + title (str): + The title to show for the link. + uri (str): + The uri of the link. + """ + + title: str = proto.Field( + proto.STRING, + number=1, + ) + uri: str = proto.Field( + proto.STRING, + number=2, + ) + + title: str = proto.Field( + proto.STRING, + number=1, + ) + description: str = proto.Field( + proto.STRING, + number=2, + ) + about_link: "Place.ConsumerAlert.Details.Link" = proto.Field( + proto.MESSAGE, + number=3, + message="Place.ConsumerAlert.Details.Link", + ) + + overview: str = proto.Field( + proto.STRING, + number=1, + ) + details: "Place.ConsumerAlert.Details" = proto.Field( + proto.MESSAGE, + number=2, + message="Place.ConsumerAlert.Details", + ) + language_code: str = proto.Field( + proto.STRING, + number=3, + ) + name: str = proto.Field( proto.STRING, number=1, @@ -1485,6 +1567,11 @@ class NeighborhoodSummary(proto.Message): number=91, message=NeighborhoodSummary, ) + consumer_alert: ConsumerAlert = proto.Field( + proto.MESSAGE, + number=92, + message=ConsumerAlert, + ) moved_place: str = proto.Field( proto.STRING, number=93, diff --git a/packages/google-maps-places/google/maps/places_v1/types/review.py b/packages/google-maps-places/google/maps/places_v1/types/review.py index 17d36a33c364..0b15b4259601 100644 --- a/packages/google-maps-places/google/maps/places_v1/types/review.py +++ b/packages/google-maps-places/google/maps/places_v1/types/review.py @@ -18,6 +18,7 @@ from typing import MutableMapping, MutableSequence from google.protobuf import timestamp_pb2 # type: ignore +from google.type import date_pb2 # type: ignore from google.type import localized_text_pb2 # type: ignore import proto # type: ignore @@ -59,6 +60,10 @@ class Review(proto.Message): the review. google_maps_uri (str): A link to show the review on Google Maps. + visit_date (google.type.date_pb2.Date): + The date when the author visited the place. + This is truncated to the year and month of the + visit. """ name: str = proto.Field( @@ -101,6 +106,11 @@ class Review(proto.Message): proto.STRING, number=16, ) + visit_date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=17, + message=date_pb2.Date, + ) __all__ = tuple(sorted(__protobuf__.manifest))